mirror of
https://gitcode.com/gh_mirrors/re/react-native-pushy.git
synced 2025-09-16 12:51:44 +08:00
Compare commits
178 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
c26080325d | ||
![]() |
ec0a9e0a3e | ||
![]() |
b34b70ed01 | ||
![]() |
fddae3d79a | ||
![]() |
7fc0d717d5 | ||
![]() |
686209d50e | ||
![]() |
80b0401b02 | ||
![]() |
786d32d92f | ||
![]() |
27327dbe12 | ||
![]() |
96a81cc36d | ||
![]() |
0aa063c584 | ||
![]() |
4d72d49fe4 | ||
![]() |
53d07406ef | ||
![]() |
d0804cfe15 | ||
![]() |
35939286d0 | ||
![]() |
f49ce30cef | ||
![]() |
e6cd25a2d8 | ||
![]() |
0cc96ee59c | ||
![]() |
6dd71a36e8 | ||
![]() |
8db8d2162e | ||
![]() |
2bf25f37f0 | ||
![]() |
ca3c3d86b5 | ||
![]() |
3edb3cca57 | ||
![]() |
d80531dbcc | ||
![]() |
07003a4767 | ||
![]() |
ee7be88542 | ||
![]() |
cac92b43c7 | ||
![]() |
e66d102e85 | ||
![]() |
94d52bb415 | ||
![]() |
775e567062 | ||
![]() |
bf1701031b | ||
![]() |
d32d395a2a | ||
![]() |
3bc63acad4 | ||
![]() |
898ed85b8c | ||
![]() |
3a526d1b15 | ||
![]() |
05563c3393 | ||
![]() |
b193b4b1df | ||
![]() |
451e298ba5 | ||
![]() |
1b5c07be9e | ||
![]() |
13cf53974e | ||
![]() |
2a1915c50c | ||
![]() |
3de78a9dbd | ||
![]() |
ef065e4072 | ||
![]() |
ff67829a27 | ||
![]() |
206a04b331 | ||
![]() |
d087c167f1 | ||
![]() |
f4c62cc3d1 | ||
![]() |
431940a423 | ||
![]() |
2dc9243bb8 | ||
![]() |
dba4a98fd0 | ||
![]() |
d4d12e1889 | ||
![]() |
daf870fd75 | ||
![]() |
33641fcbef | ||
![]() |
a02ca4fa71 | ||
![]() |
c5a2a10f9d | ||
![]() |
da7e9c6498 | ||
![]() |
30425db7b2 | ||
![]() |
61077bbc38 | ||
![]() |
29648ff56f | ||
![]() |
9080c5f325 | ||
![]() |
58c2248686 | ||
![]() |
cb736d7ec5 | ||
![]() |
f82be5a68c | ||
![]() |
df903f4a0e | ||
![]() |
8e60956af0 | ||
![]() |
6f5d12594b | ||
![]() |
bb2bf06369 | ||
![]() |
ab1250ff5c | ||
![]() |
f720f290d9 | ||
![]() |
0ccacc2f7b | ||
![]() |
1201315bd1 | ||
![]() |
ca7878a9db | ||
![]() |
f545d654dc | ||
![]() |
f8fec9b5f0 | ||
![]() |
116d9959c2 | ||
![]() |
50d98a941c | ||
![]() |
4226865970 | ||
![]() |
736b82aac6 | ||
![]() |
d9e307659f | ||
![]() |
ed135f7b4e | ||
![]() |
94cda441b2 | ||
![]() |
2097ce3128 | ||
![]() |
c4d2523a92 | ||
![]() |
48e0849804 | ||
![]() |
9d9fbd3315 | ||
![]() |
e6a8855502 | ||
![]() |
8678a748fd | ||
![]() |
6f222fcc99 | ||
![]() |
7782025e38 | ||
![]() |
69aed18b78 | ||
![]() |
29e258c131 | ||
![]() |
49e585a561 | ||
![]() |
0e89b270cc | ||
![]() |
7c8e75587b | ||
![]() |
84fee71df6 | ||
![]() |
db548d03dd | ||
![]() |
fc82addd75 | ||
![]() |
90e7c00cf6 | ||
![]() |
eea7ff26f2 | ||
![]() |
684dc8267d | ||
![]() |
5786bf8132 | ||
![]() |
1bd5fbbc94 | ||
![]() |
cd2eb9417a | ||
![]() |
7d8730f590 | ||
![]() |
e3081a02db | ||
![]() |
ec8c475c54 | ||
![]() |
ac18785e50 | ||
![]() |
e80317415c | ||
![]() |
f5c307deca | ||
![]() |
b4feae292d | ||
![]() |
a1c2679427 | ||
![]() |
17ff366f51 | ||
![]() |
3c5792423e | ||
![]() |
d071fbfc2b | ||
![]() |
17dffa1eb5 | ||
![]() |
bcd61315e9 | ||
![]() |
f626cc1933 | ||
![]() |
4ba3f25972 | ||
![]() |
cd695b1ffb | ||
![]() |
37a1a5a18b | ||
![]() |
5a2ebf8df7 | ||
![]() |
95ba5f364b | ||
![]() |
841228c341 | ||
![]() |
93049f1e54 | ||
![]() |
a966655faf | ||
![]() |
a4052091e0 | ||
![]() |
ebb5defb10 | ||
![]() |
a509ff8e30 | ||
![]() |
59fcba15ee | ||
![]() |
c6f9bb20a1 | ||
![]() |
9e6c7ea769 | ||
![]() |
f461c8ddd2 | ||
![]() |
4cbeb7bec4 | ||
![]() |
ed7f5ac606 | ||
![]() |
6abb2c7a5d | ||
![]() |
a4a372f17e | ||
![]() |
48693e3b45 | ||
![]() |
2d805fb38e | ||
![]() |
92c421b30f | ||
![]() |
dbd0880295 | ||
![]() |
f110df1206 | ||
![]() |
d17eac48f0 | ||
![]() |
8e1a639dda | ||
![]() |
5999670917 | ||
![]() |
0f6875d8d5 | ||
![]() |
3752ad4e5d | ||
![]() |
a2f01b6213 | ||
![]() |
c2499f799b | ||
![]() |
680f77a8d8 | ||
![]() |
eaae1286f4 | ||
![]() |
20a21ae894 | ||
![]() |
5abe7b181b | ||
![]() |
e859238d97 | ||
![]() |
7796090e72 | ||
![]() |
f07be8cf0b | ||
![]() |
7c8f2d493f | ||
![]() |
437eb4f10f | ||
![]() |
5053a89cfa | ||
![]() |
4a84622c04 | ||
![]() |
cf812eacda | ||
![]() |
6a031f598f | ||
![]() |
7ecf879ac9 | ||
![]() |
c779befa86 | ||
![]() |
19f060abf5 | ||
![]() |
b9c655312e | ||
![]() |
2ad4635bc6 | ||
![]() |
0d3f95d2bd | ||
![]() |
36568356dc | ||
![]() |
1a3681f308 | ||
![]() |
81f6e57413 | ||
![]() |
46c7aa88dd | ||
![]() |
22a2902f71 | ||
![]() |
e9755392ec | ||
![]() |
c28eec436d | ||
![]() |
c46fb1be3a | ||
![]() |
1d0fb7d260 | ||
![]() |
bdd97ac6ac | ||
![]() |
ba3e92e3b8 |
14
.gitignore
vendored
14
.gitignore
vendored
@@ -1,10 +1,6 @@
|
||||
/.idea
|
||||
/node_modules
|
||||
/local-cli/lib
|
||||
/react-native-pushy-cli/node_modules
|
||||
/react-native-pushy-cli/lib
|
||||
/android/build
|
||||
/android/obj
|
||||
.vscode
|
||||
android/build
|
||||
android/obj
|
||||
*.iml
|
||||
|
||||
# OSX
|
||||
@@ -45,4 +41,6 @@ local.properties
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
|
||||
Example/**/update.json
|
||||
Example/**/update.json
|
||||
yarn-error.log
|
||||
Example/testHotUpdate/.pushy
|
||||
|
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
[submodule "android/jni/lzma"]
|
||||
path = android/jni/lzma
|
||||
url = https://github.com/sisong/lzma.git
|
||||
[submodule "android/jni/HDiffPatch"]
|
||||
path = android/jni/HDiffPatch
|
||||
url = https://github.com/sisong/HDiffPatch.git
|
24
.npmignore
24
.npmignore
@@ -1,13 +1,11 @@
|
||||
/.idea
|
||||
/.babelrc
|
||||
/.npmignore
|
||||
/.eslintrc
|
||||
/.nvmrc
|
||||
/.travis.yml
|
||||
/local-cli/src
|
||||
/react-native-pushy-cli
|
||||
/Example
|
||||
/android/build
|
||||
.babelrc
|
||||
.npmignore
|
||||
.eslintrc
|
||||
.nvmrc
|
||||
.travis.yml
|
||||
Example
|
||||
android/build
|
||||
.vscode
|
||||
|
||||
# OSX
|
||||
#
|
||||
@@ -38,6 +36,8 @@ project.xcworkspace
|
||||
.idea
|
||||
.gradle
|
||||
local.properties
|
||||
android/build
|
||||
android/obj
|
||||
|
||||
# node.js
|
||||
#
|
||||
@@ -45,4 +45,6 @@ node_modules/
|
||||
npm-debug.log
|
||||
Example
|
||||
yarn.lock
|
||||
android/jni
|
||||
|
||||
domains.json
|
||||
endpoints.json
|
@@ -1,5 +1,4 @@
|
||||
module.exports = {
|
||||
printWidth: 120,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
};
|
||||
|
@@ -1,75 +0,0 @@
|
||||
[ignore]
|
||||
; We fork some components by platform
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Ignore polyfills
|
||||
node_modules/react-native/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
node_modules/warning/.*
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/LoadingView.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
node_modules/react-native/flow/
|
||||
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.ios.js
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation'
|
||||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/node_modules/react-native/\1'
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/node_modules/react-native/Libraries/Image/RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=warn
|
||||
unsafe-getters-setters=warn
|
||||
inexact-spread=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
deprecated-utility=error
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
nonstrict-import
|
||||
sketchy-null
|
||||
unclear-type
|
||||
unsafe-getters-setters
|
||||
untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.105.0
|
4
Example/testHotUpdate/.gitattributes
vendored
4
Example/testHotUpdate/.gitattributes
vendored
@@ -1 +1,3 @@
|
||||
*.pbxproj -text
|
||||
# Windows files should use crlf line endings
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
*.bat text eol=crlf
|
3
Example/testHotUpdate/.gitignore
vendored
3
Example/testHotUpdate/.gitignore
vendored
@@ -57,3 +57,6 @@ buck-out/
|
||||
|
||||
# CocoaPods
|
||||
/ios/Pods/
|
||||
|
||||
|
||||
.pushy
|
@@ -3,4 +3,5 @@ module.exports = {
|
||||
jsxBracketSameLine: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'all',
|
||||
arrowParens: 'avoid',
|
||||
};
|
||||
|
@@ -15,10 +15,12 @@ import com.android.build.OutputFile
|
||||
* // the name of the generated asset file containing your JS bundle
|
||||
* bundleAssetName: "index.android.bundle",
|
||||
*
|
||||
* // the entry file for bundle generation
|
||||
* // the entry file for bundle generation. If none specified and
|
||||
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
|
||||
* // default. Can be overridden with ENTRY_FILE environment variable.
|
||||
* entryFile: "index.android.js",
|
||||
*
|
||||
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
|
||||
* // https://reactnative.dev/docs/performance#enable-the-ram-format
|
||||
* bundleCommand: "ram-bundle",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
@@ -76,7 +78,6 @@ import com.android.build.OutputFile
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
entryFile: "index.js",
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
]
|
||||
|
||||
@@ -119,13 +120,15 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
*/
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
/**
|
||||
* Architectures to build native code for in debug.
|
||||
*/
|
||||
def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
android {
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.testhotupdate"
|
||||
@@ -137,9 +140,9 @@ android {
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
enable true
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
include "x86", "arm64-v8a"
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
@@ -153,25 +156,33 @@ android {
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.debug
|
||||
if (nativeArchitectures) {
|
||||
ndk {
|
||||
abiFilters nativeArchitectures.split(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
release {
|
||||
crunchPngs false
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
// see https://facebook.github.io/react-native/docs/signed-apk-android.
|
||||
// see https://reactnative.dev/docs/signed-apk-android.
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
}
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
||||
defaultConfig.versionCode * 1000 + versionCodes.get(abi)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -180,8 +191,24 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
exclude group:'com.squareup.okhttp3', module:'okhttp'
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.flipper'
|
||||
}
|
||||
|
||||
if (enableHermes) {
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
@@ -192,10 +219,10 @@ dependencies {
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
// puts all compile dependencies into folder libs for BUCK to use
|
||||
// puts all implementation dependencies into folder libs for BUCK to use
|
||||
task copyDownloadableDepsToLibs(type: Copy) {
|
||||
from configurations.compile
|
||||
from configurations.implementation
|
||||
into 'libs'
|
||||
}
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
@@ -4,5 +4,7 @@
|
||||
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
|
||||
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning">
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
|
||||
* directory of this source tree.
|
||||
*/
|
||||
package com.testhotupdate;
|
||||
|
||||
import android.content.Context;
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||
import com.facebook.flipper.core.FlipperClient;
|
||||
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
|
||||
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
|
||||
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class ReactNativeFlipper {
|
||||
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (FlipperUtils.shouldEnableFlipper(context)) {
|
||||
final FlipperClient client = AndroidFlipperClient.getInstance(context);
|
||||
|
||||
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
|
||||
client.addPlugin(new ReactFlipperPlugin());
|
||||
client.addPlugin(new DatabasesFlipperPlugin(context));
|
||||
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
|
||||
client.addPlugin(CrashReporterPlugin.getInstance());
|
||||
|
||||
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
|
||||
NetworkingModule.setCustomClientBuilder(
|
||||
new NetworkingModule.CustomClientBuilder() {
|
||||
@Override
|
||||
public void apply(OkHttpClient.Builder builder) {
|
||||
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
|
||||
}
|
||||
});
|
||||
client.addPlugin(networkFlipperPlugin);
|
||||
client.start();
|
||||
|
||||
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
|
||||
// Hence we run if after all native modules have been initialized
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,6 +4,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:usesCleartextTraffic="true"
|
||||
android:name=".MainApplication"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
@@ -13,14 +14,14 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@@ -4,6 +4,7 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
@@ -50,23 +51,28 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
initializeFlipper(this); // Remove this line if you don't want Flipper enabled
|
||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Flipper in React Native templates.
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
* @param reactInstanceManager
|
||||
*/
|
||||
private static void initializeFlipper(Context context) {
|
||||
private static void initializeFlipper(
|
||||
Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper");
|
||||
aClass.getMethod("initializeFlipper", Context.class).invoke(null, context);
|
||||
Class<?> aClass = Class.forName("com.testhotupdate.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
|
@@ -1,9 +1,8 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:textColor">#000000</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
@@ -2,17 +2,18 @@
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
buildToolsVersion = "28.0.3"
|
||||
minSdkVersion = 16
|
||||
compileSdkVersion = 28
|
||||
targetSdkVersion = 28
|
||||
buildToolsVersion = "30.0.2"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 30
|
||||
targetSdkVersion = 30
|
||||
ndkVersion = "21.4.7075529"
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath('com.android.tools.build:gradle:3.5.1')
|
||||
classpath('com.android.tools.build:gradle:4.2.2')
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@@ -21,6 +22,7 @@ buildscript {
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
@@ -32,7 +34,6 @@ allprojects {
|
||||
}
|
||||
|
||||
google()
|
||||
jcenter()
|
||||
maven { url 'https://jitpack.io' }
|
||||
maven { url 'https://www.jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
@@ -17,5 +17,12 @@
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.99.0
|
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
37
Example/testHotUpdate/android/gradlew
vendored
37
Example/testHotUpdate/android/gradlew
vendored
@@ -7,7 +7,7 @@
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -125,8 +125,8 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
@@ -154,19 +154,19 @@ if $cygwin ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +175,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
exec "$JAVACMD" "$@"
|
189
Example/testHotUpdate/android/gradlew.bat
vendored
189
Example/testHotUpdate/android/gradlew.bat
vendored
@@ -1,100 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
@@ -1,39 +1,26 @@
|
||||
platform :ios, '9.0'
|
||||
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
platform :ios, '11.0'
|
||||
|
||||
target 'testHotUpdate' do
|
||||
# Pods for testHotUpdate
|
||||
pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
|
||||
pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
|
||||
pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
|
||||
pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
|
||||
pod 'React', :path => '../node_modules/react-native/'
|
||||
pod 'React-Core', :path => '../node_modules/react-native/'
|
||||
pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
|
||||
pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
|
||||
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
|
||||
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
|
||||
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
|
||||
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
|
||||
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
|
||||
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
|
||||
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
|
||||
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
|
||||
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
|
||||
pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'
|
||||
config = use_native_modules!
|
||||
|
||||
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
||||
pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
|
||||
pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
use_react_native!(
|
||||
:path => config[:reactNativePath],
|
||||
# to enable hermes on iOS, change `false` to `true` and then install pods
|
||||
:hermes_enabled => false
|
||||
)
|
||||
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# you should disable the next line.
|
||||
use_flipper!({ "Flipper-DoubleConversion" => "1.1.7" })
|
||||
|
||||
use_native_modules!
|
||||
post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
end
|
||||
end
|
||||
|
||||
|
@@ -1,245 +1,390 @@
|
||||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- boost (1.76.0)
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.61.4)
|
||||
- FBReactNativeSpec (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.61.4)
|
||||
- RCTTypeSafety (= 0.61.4)
|
||||
- React-Core (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- ReactCommon/turbomodule/core (= 0.61.4)
|
||||
- Folly (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
- Folly/Default (= 2018.10.22.00)
|
||||
- glog
|
||||
- Folly/Default (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- FBLazyVector (0.66.0)
|
||||
- FBReactNativeSpec (0.66.0):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.66.0)
|
||||
- RCTTypeSafety (= 0.66.0)
|
||||
- React-Core (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- Flipper (0.99.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- Flipper-RSocket (~> 1.4)
|
||||
- Flipper-Boost-iOSX (1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (1.1.7)
|
||||
- Flipper-Fmt (7.1.7)
|
||||
- Flipper-Folly (2.6.7):
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Glog
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.180)
|
||||
- Flipper-Glog (0.3.6)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.4.3):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit (0.99.0):
|
||||
- FlipperKit/Core (= 0.99.0)
|
||||
- FlipperKit/Core (0.99.0):
|
||||
- Flipper (~> 0.99.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- FlipperKit/CppBridge (0.99.0):
|
||||
- Flipper (~> 0.99.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.99.0):
|
||||
- Flipper-Folly (~> 2.6)
|
||||
- FlipperKit/FBDefines (0.99.0)
|
||||
- FlipperKit/FKPortForwarding (0.99.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.99.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitReactPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.99.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- fmt (6.2.1)
|
||||
- glog (0.3.5)
|
||||
- RCTRequired (0.61.4)
|
||||
- RCTTypeSafety (0.61.4):
|
||||
- FBLazyVector (= 0.61.4)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTRequired (= 0.61.4)
|
||||
- React-Core (= 0.61.4)
|
||||
- React (0.61.4):
|
||||
- React-Core (= 0.61.4)
|
||||
- React-Core/DevSupport (= 0.61.4)
|
||||
- React-Core/RCTWebSocket (= 0.61.4)
|
||||
- React-RCTActionSheet (= 0.61.4)
|
||||
- React-RCTAnimation (= 0.61.4)
|
||||
- React-RCTBlob (= 0.61.4)
|
||||
- React-RCTImage (= 0.61.4)
|
||||
- React-RCTLinking (= 0.61.4)
|
||||
- React-RCTNetwork (= 0.61.4)
|
||||
- React-RCTSettings (= 0.61.4)
|
||||
- React-RCTText (= 0.61.4)
|
||||
- React-RCTVibration (= 0.61.4)
|
||||
- React-Core (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.4)
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/Default (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.4)
|
||||
- React-Core/RCTWebSocket (= 0.61.4)
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- React-jsinspector (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.61.4):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.61.4)
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsiexecutor (= 0.61.4)
|
||||
- Yoga
|
||||
- React-CoreModules (0.61.4):
|
||||
- FBReactNativeSpec (= 0.61.4)
|
||||
- Folly (= 2018.10.22.00)
|
||||
- RCTTypeSafety (= 0.61.4)
|
||||
- React-Core/CoreModulesHeaders (= 0.61.4)
|
||||
- React-RCTImage (= 0.61.4)
|
||||
- ReactCommon/turbomodule/core (= 0.61.4)
|
||||
- React-cxxreact (0.61.4):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- libevent (2.1.12)
|
||||
- OpenSSL-Universal (1.1.180)
|
||||
- RCT-Folly (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- React-jsinspector (= 0.61.4)
|
||||
- React-jsi (0.61.4):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- RCT-Folly/Default (= 2021.06.28.00-v2)
|
||||
- RCT-Folly/Default (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- React-jsi/Default (= 0.61.4)
|
||||
- React-jsi/Default (0.61.4):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- RCTRequired (0.66.0)
|
||||
- RCTTypeSafety (0.66.0):
|
||||
- FBLazyVector (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.66.0)
|
||||
- React-Core (= 0.66.0)
|
||||
- React (0.66.0):
|
||||
- React-Core (= 0.66.0)
|
||||
- React-Core/DevSupport (= 0.66.0)
|
||||
- React-Core/RCTWebSocket (= 0.66.0)
|
||||
- React-RCTActionSheet (= 0.66.0)
|
||||
- React-RCTAnimation (= 0.66.0)
|
||||
- React-RCTBlob (= 0.66.0)
|
||||
- React-RCTImage (= 0.66.0)
|
||||
- React-RCTLinking (= 0.66.0)
|
||||
- React-RCTNetwork (= 0.66.0)
|
||||
- React-RCTSettings (= 0.66.0)
|
||||
- React-RCTText (= 0.66.0)
|
||||
- React-RCTVibration (= 0.66.0)
|
||||
- React-callinvoker (0.66.0)
|
||||
- React-Core (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.66.0)
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/Default (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.66.0)
|
||||
- React-Core/RCTWebSocket (= 0.66.0)
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-jsinspector (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.66.0):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.66.0)
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsiexecutor (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- Yoga
|
||||
- React-CoreModules (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.0)
|
||||
- React-Core/CoreModulesHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-RCTImage (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-cxxreact (0.66.0):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsiexecutor (0.61.4):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-jsinspector (= 0.66.0)
|
||||
- React-logger (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- React-runtimeexecutor (= 0.66.0)
|
||||
- React-jsi (0.66.0):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-jsinspector (0.61.4)
|
||||
- react-native-update (5.5.0):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.66.0)
|
||||
- React-jsi/Default (0.66.0):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.66.0):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- React-jsinspector (0.66.0)
|
||||
- React-logger (0.66.0):
|
||||
- glog
|
||||
- react-native-update (6.3.0):
|
||||
- React
|
||||
- react-native-update/BSDiff (= 5.5.0)
|
||||
- react-native-update/RCTPushy (= 5.5.0)
|
||||
- react-native-update/HDiffPatch (= 6.3.0)
|
||||
- react-native-update/RCTPushy (= 6.3.0)
|
||||
- SSZipArchive
|
||||
- react-native-update/BSDiff (5.5.0):
|
||||
- react-native-update/HDiffPatch (6.3.0):
|
||||
- React
|
||||
- SSZipArchive
|
||||
- react-native-update/RCTPushy (5.5.0):
|
||||
- react-native-update/RCTPushy (6.3.0):
|
||||
- React
|
||||
- SSZipArchive
|
||||
- React-RCTActionSheet (0.61.4):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.61.4)
|
||||
- React-RCTAnimation (0.61.4):
|
||||
- React-Core/RCTAnimationHeaders (= 0.61.4)
|
||||
- React-RCTBlob (0.61.4):
|
||||
- React-Core/RCTBlobHeaders (= 0.61.4)
|
||||
- React-Core/RCTWebSocket (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- React-RCTNetwork (= 0.61.4)
|
||||
- React-RCTImage (0.61.4):
|
||||
- React-Core/RCTImageHeaders (= 0.61.4)
|
||||
- React-RCTNetwork (= 0.61.4)
|
||||
- React-RCTLinking (0.61.4):
|
||||
- React-Core/RCTLinkingHeaders (= 0.61.4)
|
||||
- React-RCTNetwork (0.61.4):
|
||||
- React-Core/RCTNetworkHeaders (= 0.61.4)
|
||||
- React-RCTSettings (0.61.4):
|
||||
- React-Core/RCTSettingsHeaders (= 0.61.4)
|
||||
- React-RCTText (0.61.4):
|
||||
- React-Core/RCTTextHeaders (= 0.61.4)
|
||||
- React-RCTVibration (0.61.4):
|
||||
- React-Core/RCTVibrationHeaders (= 0.61.4)
|
||||
- ReactCommon/jscallinvoker (0.61.4):
|
||||
- React-perflogger (0.66.0)
|
||||
- React-RCTActionSheet (0.66.0):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.66.0)
|
||||
- React-RCTAnimation (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.0)
|
||||
- React-Core/RCTAnimationHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-RCTBlob (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTBlobHeaders (= 0.66.0)
|
||||
- React-Core/RCTWebSocket (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-RCTNetwork (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-RCTImage (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.0)
|
||||
- React-Core/RCTImageHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-RCTNetwork (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-RCTLinking (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- React-Core/RCTLinkingHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-RCTNetwork (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.0)
|
||||
- React-Core/RCTNetworkHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-RCTSettings (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.66.0)
|
||||
- React-Core/RCTSettingsHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-RCTText (0.66.0):
|
||||
- React-Core/RCTTextHeaders (= 0.66.0)
|
||||
- React-RCTVibration (0.66.0):
|
||||
- FBReactNativeSpec (= 0.66.0)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTVibrationHeaders (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (= 0.66.0)
|
||||
- React-runtimeexecutor (0.66.0):
|
||||
- React-jsi (= 0.66.0)
|
||||
- ReactCommon/turbomodule/core (0.66.0):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- ReactCommon/turbomodule/core (0.61.4):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-Core (= 0.61.4)
|
||||
- React-cxxreact (= 0.61.4)
|
||||
- React-jsi (= 0.61.4)
|
||||
- ReactCommon/jscallinvoker (= 0.61.4)
|
||||
- SSZipArchive (2.2.2)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.66.0)
|
||||
- React-Core (= 0.66.0)
|
||||
- React-cxxreact (= 0.66.0)
|
||||
- React-jsi (= 0.66.0)
|
||||
- React-logger (= 0.66.0)
|
||||
- React-perflogger (= 0.66.0)
|
||||
- SSZipArchive (2.4.2)
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
- Yoga (~> 1.14)
|
||||
|
||||
DEPENDENCIES:
|
||||
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Flipper (= 0.99.0)
|
||||
- Flipper-Boost-iOSX (= 1.76.0.1.11)
|
||||
- Flipper-DoubleConversion (= 1.1.7)
|
||||
- Flipper-Fmt (= 7.1.7)
|
||||
- Flipper-Folly (= 2.6.7)
|
||||
- Flipper-Glog (= 0.3.6)
|
||||
- Flipper-PeerTalk (= 0.0.4)
|
||||
- Flipper-RSocket (= 1.4.3)
|
||||
- FlipperKit (= 0.99.0)
|
||||
- FlipperKit/Core (= 0.99.0)
|
||||
- FlipperKit/CppBridge (= 0.99.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.99.0)
|
||||
- FlipperKit/FBDefines (= 0.99.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.99.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.99.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.99.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.99.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.99.0)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
@@ -248,7 +393,9 @@ DEPENDENCIES:
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-logger (from `../node_modules/react-native/ReactCommon/logger`)
|
||||
- react-native-update (from `../../..`)
|
||||
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
|
||||
@@ -258,32 +405,49 @@ DEPENDENCIES:
|
||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`)
|
||||
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- boost-for-react-native
|
||||
- CocoaAsyncSocket
|
||||
- Flipper
|
||||
- Flipper-Boost-iOSX
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Fmt
|
||||
- Flipper-Folly
|
||||
- Flipper-Glog
|
||||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- fmt
|
||||
- libevent
|
||||
- OpenSSL-Universal
|
||||
- SSZipArchive
|
||||
- YogaKit
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
boost:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec"
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
FBLazyVector:
|
||||
:path: "../node_modules/react-native/Libraries/FBLazyVector"
|
||||
FBReactNativeSpec:
|
||||
:path: "../node_modules/react-native/Libraries/FBReactNativeSpec"
|
||||
Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
|
||||
:path: "../node_modules/react-native/React/FBReactNativeSpec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
RCT-Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec"
|
||||
RCTRequired:
|
||||
:path: "../node_modules/react-native/Libraries/RCTRequired"
|
||||
RCTTypeSafety:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
@@ -296,8 +460,12 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-logger:
|
||||
:path: "../node_modules/react-native/ReactCommon/logger"
|
||||
react-native-update:
|
||||
:path: "../../.."
|
||||
React-perflogger:
|
||||
:path: "../node_modules/react-native/ReactCommon/reactperflogger"
|
||||
React-RCTActionSheet:
|
||||
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
|
||||
React-RCTAnimation:
|
||||
@@ -316,41 +484,61 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/Text"
|
||||
React-RCTVibration:
|
||||
:path: "../node_modules/react-native/Libraries/Vibration"
|
||||
React-runtimeexecutor:
|
||||
:path: "../node_modules/react-native/ReactCommon/runtimeexecutor"
|
||||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
Yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
FBLazyVector: feb35a6b7f7b50f367be07f34012f34a79282fa3
|
||||
FBReactNativeSpec: 51477b84b1bf7ab6f9ef307c24e3dd675391be44
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
RCTRequired: f3b3fb6f4723e8e52facb229d0c75fdc76773849
|
||||
RCTTypeSafety: 2ec60de6abb1db050b56ecc4b60188026078fd10
|
||||
React: 10e0130b57e55a7cd8c3dee37c1261102ce295f4
|
||||
React-Core: 636212410772d05f3a1eb79d965df2962ca1c70b
|
||||
React-CoreModules: 6f70d5e41919289c582f88c9ad9923fe5c87400a
|
||||
React-cxxreact: ddecbe9157ec1743f52ea17bf8d95debc0d6e846
|
||||
React-jsi: ca921f4041505f9d5197139b2d09eeb020bb12e8
|
||||
React-jsiexecutor: 8dfb73b987afa9324e4009bdce62a18ce23d983c
|
||||
React-jsinspector: d15478d0a8ada19864aa4d1cc1c697b41b3fa92f
|
||||
react-native-update: 0696134a23c2ad1be899c12b33f9d3521284d458
|
||||
React-RCTActionSheet: 7369b7c85f99b6299491333affd9f01f5a130c22
|
||||
React-RCTAnimation: d07be15b2bd1d06d89417eb0343f98ffd2b099a7
|
||||
React-RCTBlob: 8e0b23d95c9baa98f6b0e127e07666aaafd96c34
|
||||
React-RCTImage: 443050d14a66e8c2332e9c055f45689d23e15cc7
|
||||
React-RCTLinking: ce9a90ba155aec41be49e75ec721bbae2d48a47e
|
||||
React-RCTNetwork: 41fe54bacc67dd00e6e4c4d30dd98a13e4beabc8
|
||||
React-RCTSettings: 45e3e0a6470310b2dab2ccc6d1d73121ba3ea936
|
||||
React-RCTText: 21934e0a51d522abcd0a275407e80af45d6fd9ec
|
||||
React-RCTVibration: 0f76400ee3cec6edb9c125da49fed279340d145a
|
||||
ReactCommon: a6a294e7028ed67b926d29551aa9394fd989c24c
|
||||
SSZipArchive: fa16b8cc4cdeceb698e5e5d9f67e9558532fbf23
|
||||
Yoga: ba3d99dbee6c15ea6bbe3783d1f0cb1ffb79af0f
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: 6816ca39e1cc8beffd2a96783f518296789d1c48
|
||||
FBReactNativeSpec: 3b1e86618e902743fde35b40cf9ebd100fd655b7
|
||||
Flipper: 30e8eeeed6abdc98edaf32af0cda2f198be4b733
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
|
||||
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
|
||||
Flipper-Folly: 83af37379faa69497529e414bd43fbfc7cae259a
|
||||
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
|
||||
FlipperKit: d8d346844eca5d9120c17d441a2f38596e8ed2b9
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: 5337263514dd6f09803962437687240c5dc39aa4
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
|
||||
RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9
|
||||
RCTRequired: e4a18a90004e0ed97bba9081099104fd0f658dc9
|
||||
RCTTypeSafety: 8a3c31d38de58e1a6a7df6e4e643644a60b00e22
|
||||
React: 2b1d0dc3c23e01b754588a74a5b265282d9eb61e
|
||||
React-callinvoker: 57c195e780695285fa56e61efdbc0ca0e9204484
|
||||
React-Core: 45e4b3c57b0b5fdbb24bc6a63a964870c0405955
|
||||
React-CoreModules: d7bb1ae3436eddd85a7eb6d5e928f8c1655d87db
|
||||
React-cxxreact: 60c850e9997b21ee302757c36a460efc944183e7
|
||||
React-jsi: 38d68cb1b53843703100830d530342b32f8e0878
|
||||
React-jsiexecutor: 6a05173dc0142abc582bd4edd2d23146b8cc218a
|
||||
React-jsinspector: be95ad424ba9f7b817aff22732eb9b1b810a000a
|
||||
React-logger: 9a9cd87d4ea681ae929b32ef580638ff1b50fb24
|
||||
react-native-update: 0fc93e720f09bf7b465292dcd2fb8d8db3aef763
|
||||
React-perflogger: 1f554c2b684e2f484f9edcdfdaeedab039fbaca8
|
||||
React-RCTActionSheet: 610d5a5d71ab4808734782c8bca6a12ec3563672
|
||||
React-RCTAnimation: ec6ed97370ace32724c253f29f0586cafcab8126
|
||||
React-RCTBlob: b3270d498ff240f49c50e1bc950b6e5fd48886ba
|
||||
React-RCTImage: 23d5e26669b31230bea3fd99eb703af699e5d61a
|
||||
React-RCTLinking: edaaee9dee82b79e90e7b903d8913fa72284fbba
|
||||
React-RCTNetwork: e8825053dd1b5c2a0e1aa3cf1127750b624f90c0
|
||||
React-RCTSettings: 40d7ae987031c5dc561d11cd3a15cc1245a11d42
|
||||
React-RCTText: 6e104479d4f0bb593b4cf90b6fc6e5390c12ccde
|
||||
React-RCTVibration: 53b92d54b923283638cb0186da7a5c2d2b70a49b
|
||||
React-runtimeexecutor: 4bb657a97aa74568d9ed634c8bd478299bb8a3a6
|
||||
ReactCommon: eb059748e842a1a86025ebbd4ac9d99e74492f88
|
||||
SSZipArchive: e7b4f3d9e780c2acc1764cd88fbf2de28f26e5b2
|
||||
Yoga: c11abbf5809216c91fcd62f5571078b83d9b6720
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 244ba888c650d3945bf72a8d01516fb0f1b3b097
|
||||
PODFILE CHECKSUM: a26b18e70d6c4725e0254b56751afbc7620020ff
|
||||
|
||||
COCOAPODS: 1.8.4
|
||||
COCOAPODS: 1.11.2
|
||||
|
9
Example/testHotUpdate/ios/dummy.swift
Normal file
9
Example/testHotUpdate/ios/dummy.swift
Normal file
@@ -0,0 +1,9 @@
|
||||
//
|
||||
// dummy.swift
|
||||
// testHotUpdate
|
||||
//
|
||||
// Created by Qingming, Sunny Luo on 9/1/20.
|
||||
// Copyright © 2020 Facebook. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
@@ -0,0 +1,4 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
@@ -12,11 +12,11 @@
|
||||
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
|
||||
7610A16EF1CB8A7644EAFA55 /* libPods-testHotUpdate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28C264AEBE1E206870F9D871 /* libPods-testHotUpdate.a */; };
|
||||
F1CBCFD724FE1CF80019170D /* dummy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1CBCFD624FE1CF80019170D /* dummy.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; };
|
||||
0583A8BB0D57980C590354CD /* Pods-testHotUpdate-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdate-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-testHotUpdate-tvOSTests/Pods-testHotUpdate-tvOSTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
13B07F961A680F5B00A75B9A /* testHotUpdate.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = testHotUpdate.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = testHotUpdate/AppDelegate.h; sourceTree = "<group>"; };
|
||||
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = testHotUpdate/AppDelegate.m; sourceTree = "<group>"; };
|
||||
@@ -26,17 +26,10 @@
|
||||
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = testHotUpdate/main.m; sourceTree = "<group>"; };
|
||||
1A3E77317B15A5C3816ACE3A /* Pods-testHotUpdate.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdate.release.xcconfig"; path = "Target Support Files/Pods-testHotUpdate/Pods-testHotUpdate.release.xcconfig"; sourceTree = "<group>"; };
|
||||
28C264AEBE1E206870F9D871 /* libPods-testHotUpdate.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotUpdate.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
5975B699C3CC54D97D7D17AC /* Pods-testHotUpdate-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdate-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-testHotUpdate-tvOS/Pods-testHotUpdate-tvOS.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
84EBA9C1A760F4136B306391 /* Pods-testHotUpdate.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdate.debug.xcconfig"; path = "Target Support Files/Pods-testHotUpdate/Pods-testHotUpdate.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
8D1BC055E138B80CD38184D9 /* libPods-testHotUpdate-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotUpdate-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
95A532A9388B822764C95FE7 /* libPods-testHotUpdateTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotUpdateTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9E6234BBCA688ADDFBCB18E0 /* Pods-testHotUpdate-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdate-tvOS.release.xcconfig"; path = "Target Support Files/Pods-testHotUpdate-tvOS/Pods-testHotUpdate-tvOS.release.xcconfig"; sourceTree = "<group>"; };
|
||||
A210EF57CA3ECCF4BA22ACD7 /* libPods-testHotUpdate-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-testHotUpdate-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
C29B96E519A1834F3DC4E653 /* Pods-testHotUpdateTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdateTests.debug.xcconfig"; path = "Target Support Files/Pods-testHotUpdateTests/Pods-testHotUpdateTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
DBD82A01837CBC988265B839 /* Pods-testHotUpdate-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdate-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-testHotUpdate-tvOSTests/Pods-testHotUpdate-tvOSTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
ED1DB2CEADC1A82A43867C0E /* Pods-testHotUpdateTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-testHotUpdateTests.release.xcconfig"; path = "Target Support Files/Pods-testHotUpdateTests/Pods-testHotUpdateTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; };
|
||||
F1CBCFD524FE1CF80019170D /* testHotUpdate-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "testHotUpdate-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
F1CBCFD624FE1CF80019170D /* dummy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = dummy.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -56,12 +49,6 @@
|
||||
children = (
|
||||
84EBA9C1A760F4136B306391 /* Pods-testHotUpdate.debug.xcconfig */,
|
||||
1A3E77317B15A5C3816ACE3A /* Pods-testHotUpdate.release.xcconfig */,
|
||||
5975B699C3CC54D97D7D17AC /* Pods-testHotUpdate-tvOS.debug.xcconfig */,
|
||||
9E6234BBCA688ADDFBCB18E0 /* Pods-testHotUpdate-tvOS.release.xcconfig */,
|
||||
DBD82A01837CBC988265B839 /* Pods-testHotUpdate-tvOSTests.debug.xcconfig */,
|
||||
0583A8BB0D57980C590354CD /* Pods-testHotUpdate-tvOSTests.release.xcconfig */,
|
||||
C29B96E519A1834F3DC4E653 /* Pods-testHotUpdateTests.debug.xcconfig */,
|
||||
ED1DB2CEADC1A82A43867C0E /* Pods-testHotUpdateTests.release.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
@@ -76,6 +63,8 @@
|
||||
13B07FB61A68108700A75B9A /* Info.plist */,
|
||||
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
|
||||
13B07FB71A68108700A75B9A /* main.m */,
|
||||
F1CBCFD624FE1CF80019170D /* dummy.swift */,
|
||||
F1CBCFD524FE1CF80019170D /* testHotUpdate-Bridging-Header.h */,
|
||||
);
|
||||
name = testHotUpdate;
|
||||
sourceTree = "<group>";
|
||||
@@ -84,11 +73,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
|
||||
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
|
||||
28C264AEBE1E206870F9D871 /* libPods-testHotUpdate.a */,
|
||||
8D1BC055E138B80CD38184D9 /* libPods-testHotUpdate-tvOS.a */,
|
||||
A210EF57CA3ECCF4BA22ACD7 /* libPods-testHotUpdate-tvOSTests.a */,
|
||||
95A532A9388B822764C95FE7 /* libPods-testHotUpdateTests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -136,6 +121,7 @@
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
1CD78CE8A2E7B88FAE48FCEE /* [CP] Copy Pods Resources */,
|
||||
F9FE0A60F5C1B623C43151B4 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -154,6 +140,12 @@
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0940;
|
||||
ORGANIZATIONNAME = Facebook;
|
||||
TargetAttributes = {
|
||||
13B07F861A680F5B00A75B9A = {
|
||||
DevelopmentTeam = JD75Q9JJL2;
|
||||
LastSwiftMigration = 1160;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotUpdate" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
@@ -199,7 +191,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
|
||||
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
};
|
||||
1CD78CE8A2E7B88FAE48FCEE /* [CP] Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -208,10 +200,12 @@
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-testHotUpdate/Pods-testHotUpdate-resources.sh",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
"${PODS_ROOT}/../../../../ios/pushy_build_time.txt",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pushy_build_time.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -241,6 +235,24 @@
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
F9FE0A60F5C1B623C43151B4 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-testHotUpdate/Pods-testHotUpdate-frameworks.sh",
|
||||
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-testHotUpdate/Pods-testHotUpdate-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FD10A7F022414F080027D42C /* Start Packager */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -268,6 +280,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
|
||||
F1CBCFD724FE1CF80019170D /* dummy.swift in Sources */,
|
||||
13B07FC11A68108700A75B9A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -292,9 +305,12 @@
|
||||
baseConfigurationReference = 84EBA9C1A760F4136B306391 /* Pods-testHotUpdate.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = JD75Q9JJL2;
|
||||
INFOPLIST_FILE = testHotUpdate/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -303,6 +319,9 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = testHotUpdate;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "testHotUpdate-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -312,8 +331,11 @@
|
||||
baseConfigurationReference = 1A3E77317B15A5C3816ACE3A /* Pods-testHotUpdate.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = JD75Q9JJL2;
|
||||
INFOPLIST_FILE = testHotUpdate/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
@@ -322,6 +344,8 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = testHotUpdate;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "testHotUpdate-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
@@ -357,6 +381,7 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
@@ -410,6 +435,7 @@
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 ";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
|
@@ -55,6 +55,15 @@
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "testHotUpdate.app"
|
||||
BlueprintName = "testHotUpdate"
|
||||
ReferencedContainer = "container:testHotUpdate.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
@@ -67,17 +76,6 @@
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "13B07F861A680F5B00A75B9A"
|
||||
BuildableName = "testHotUpdate.app"
|
||||
BlueprintName = "testHotUpdate"
|
||||
ReferencedContainer = "container:testHotUpdate.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
@@ -99,8 +97,6 @@
|
||||
ReferencedContainer = "container:testHotUpdate.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
@@ -12,10 +12,32 @@
|
||||
#import <React/RCTRootView.h>
|
||||
#import "RCTPushy.h"
|
||||
|
||||
#ifdef FB_SONARKIT_ENABLED
|
||||
#import <FlipperKit/FlipperClient.h>
|
||||
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
|
||||
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
|
||||
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
|
||||
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
|
||||
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
|
||||
static void InitializeFlipper(UIApplication *application) {
|
||||
FlipperClient *client = [FlipperClient sharedClient];
|
||||
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
|
||||
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
|
||||
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
|
||||
[client addPlugin:[FlipperKitReactPlugin new]];
|
||||
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
|
||||
[client start];
|
||||
}
|
||||
#endif
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
#ifdef FB_SONARKIT_ENABLED
|
||||
InitializeFlipper(application);
|
||||
#endif
|
||||
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"testHotUpdate"
|
||||
|
@@ -2,37 +2,52 @@
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "3x"
|
||||
"scale" : "3x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "2x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"scale" : "3x",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"idiom" : "ios-marketing",
|
||||
"scale" : "1x",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@ module.exports = {
|
||||
getTransformOptions: async () => ({
|
||||
transform: {
|
||||
experimentalImportSupport: false,
|
||||
inlineRequires: false,
|
||||
inlineRequires: true,
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
@@ -7,22 +7,23 @@
|
||||
"ios": "react-native run-ios",
|
||||
"start": "react-native start",
|
||||
"test": "jest",
|
||||
"lint": "eslint ."
|
||||
"lint": "eslint .",
|
||||
"apk": "(cd android && ./gradlew aR)"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.9.0",
|
||||
"react-native": "0.61.4",
|
||||
"react": "17.0.2",
|
||||
"react-native": "0.66.0",
|
||||
"react-native-update": "link:../.."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.2",
|
||||
"@babel/runtime": "^7.6.2",
|
||||
"@react-native-community/eslint-config": "^0.0.5",
|
||||
"babel-jest": "^24.9.0",
|
||||
"eslint": "^6.5.1",
|
||||
"jest": "^24.9.0",
|
||||
"metro-react-native-babel-preset": "^0.56.0",
|
||||
"react-test-renderer": "16.9.0"
|
||||
"@babel/core": "^7.12.9",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@react-native-community/eslint-config": "^2.0.0",
|
||||
"babel-jest": "^26.6.3",
|
||||
"eslint": "7.14.0",
|
||||
"jest": "^26.6.3",
|
||||
"metro-react-native-babel-preset": "^0.66.2",
|
||||
"react-test-renderer": "17.0.2"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
|
76
Example/testHotUpdate/src/TestConsole.js
Normal file
76
Example/testHotUpdate/src/TestConsole.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Modal,
|
||||
TextInput,
|
||||
Button,
|
||||
NativeModules,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
Text,
|
||||
View,
|
||||
} from 'react-native';
|
||||
|
||||
const Pushy = NativeModules.Pushy;
|
||||
export default function TestConsole({visible}) {
|
||||
const [text, setText] = React.useState('');
|
||||
const [running, setRunning] = React.useState(false);
|
||||
return (
|
||||
<Modal visible={visible}>
|
||||
<SafeAreaView style={{flex: 1, padding: 10}}>
|
||||
<Text>调试Pushy方法(方法名,参数,值换行)</Text>
|
||||
<TextInput
|
||||
autoCorrect={false}
|
||||
autoCapitalize="none"
|
||||
style={{
|
||||
borderWidth: StyleSheet.hairlineWidth * 4,
|
||||
borderColor: 'black',
|
||||
height: '30%',
|
||||
marginTop: 20,
|
||||
marginBottom: 20,
|
||||
padding: 10,
|
||||
fontSize: 20,
|
||||
}}
|
||||
textAlignVertical="top"
|
||||
multiline={true}
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
/>
|
||||
{running && <ActivityIndicator />}
|
||||
<Button
|
||||
title="执行"
|
||||
onPress={async () => {
|
||||
setRunning(true);
|
||||
try {
|
||||
const inputs = text.split('\n');
|
||||
const methodName = inputs[0];
|
||||
let params;
|
||||
if (inputs.length === 1) {
|
||||
await Pushy[methodName]();
|
||||
} else {
|
||||
if (inputs.length === 2) {
|
||||
params = inputs[1];
|
||||
} else {
|
||||
params = {};
|
||||
for (let i = 1; i < inputs.length; i += 2) {
|
||||
params[inputs[i]] = inputs[i + 1];
|
||||
}
|
||||
console.log({inputs, params});
|
||||
}
|
||||
await Pushy[methodName](params);
|
||||
}
|
||||
Alert.alert('done');
|
||||
} catch (e) {
|
||||
Alert.alert(e.message);
|
||||
}
|
||||
setRunning(false);
|
||||
}}
|
||||
/>
|
||||
<View style={{marginTop: 15}}>
|
||||
<Button title="重置" onPress={() => setText('')} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Modal>
|
||||
);
|
||||
}
|
@@ -20,12 +20,20 @@ import {
|
||||
switchVersion,
|
||||
switchVersionLater,
|
||||
markSuccess,
|
||||
downloadAndInstallApk,
|
||||
cInfo,
|
||||
} from 'react-native-update';
|
||||
|
||||
import TestConsole from './TestConsole';
|
||||
|
||||
import _updateConfig from '../update.json';
|
||||
const {appKey} = _updateConfig[Platform.OS];
|
||||
|
||||
export default class App extends Component {
|
||||
state = {
|
||||
received: 0,
|
||||
total: 0,
|
||||
showTestConsole: false,
|
||||
};
|
||||
componentDidMount() {
|
||||
if (isRolledBack) {
|
||||
Alert.alert('提示', '刚刚更新失败了,版本被回滚.');
|
||||
@@ -51,22 +59,36 @@ export default class App extends Component {
|
||||
}
|
||||
}
|
||||
doUpdate = async info => {
|
||||
const hash = await downloadUpdate(info);
|
||||
Alert.alert('提示', '下载完毕,是否重启应用?', [
|
||||
{
|
||||
text: '是',
|
||||
onPress: () => {
|
||||
switchVersion(hash);
|
||||
try {
|
||||
const hash = await downloadUpdate(info, {
|
||||
onDownloadProgress: ({received, total}) => {
|
||||
this.setState({
|
||||
received,
|
||||
total,
|
||||
});
|
||||
},
|
||||
},
|
||||
{text: '否'},
|
||||
{
|
||||
text: '下次启动时',
|
||||
onPress: () => {
|
||||
switchVersionLater(hash);
|
||||
});
|
||||
if (!hash) {
|
||||
return;
|
||||
}
|
||||
Alert.alert('提示', '下载完毕,是否重启应用?', [
|
||||
{
|
||||
text: '是',
|
||||
onPress: () => {
|
||||
switchVersion(hash);
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
{text: '否'},
|
||||
{
|
||||
text: '下次启动时',
|
||||
onPress: () => {
|
||||
switchVersionLater(hash);
|
||||
},
|
||||
},
|
||||
]);
|
||||
} catch (err) {
|
||||
Alert.alert('更新失败', err.message);
|
||||
}
|
||||
};
|
||||
|
||||
checkUpdate = async () => {
|
||||
@@ -74,15 +96,33 @@ export default class App extends Component {
|
||||
try {
|
||||
info = await checkUpdate(appKey);
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
Alert.alert('更新检查失败', err.message);
|
||||
return;
|
||||
}
|
||||
if (info.expired) {
|
||||
Alert.alert('提示', '您的应用版本已更新,请前往应用商店下载新的版本', [
|
||||
Alert.alert('提示', '您的应用版本已更新,点击确定下载安装新版本', [
|
||||
{
|
||||
text: '确定',
|
||||
onPress: () => {
|
||||
info.downloadUrl && Linking.openURL(info.downloadUrl);
|
||||
if (info.downloadUrl) {
|
||||
// apk可直接下载安装
|
||||
if (
|
||||
Platform.OS === 'android' &&
|
||||
info.downloadUrl.endsWith('.apk')
|
||||
) {
|
||||
downloadAndInstallApk({
|
||||
url: info.downloadUrl,
|
||||
onDownloadProgress: ({received, total}) => {
|
||||
this.setState({
|
||||
received,
|
||||
total,
|
||||
});
|
||||
},
|
||||
});
|
||||
} else {
|
||||
Linking.openURL(info.downloadUrl);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
]);
|
||||
@@ -106,24 +146,39 @@ export default class App extends Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {received, total, showTestConsole} = this.state;
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.welcome}>欢迎使用热更新服务</Text>
|
||||
<Image
|
||||
resizeMode={'contain'}
|
||||
source={require('./assets/shoucang.png')}
|
||||
source={require('./assets/shezhi.png')}
|
||||
style={styles.image}
|
||||
/>
|
||||
<Text style={styles.instructions}>
|
||||
这是版本一 {'\n'}
|
||||
当前包版本号: {packageVersion}
|
||||
当前原生包版本号: {packageVersion}
|
||||
{'\n'}
|
||||
当前版本Hash: {currentVersion || '(空)'}
|
||||
当前热更新版本Hash: {currentVersion || '(空)'}
|
||||
{'\n'}
|
||||
</Text>
|
||||
<Text>
|
||||
下载进度:{received} / {total}
|
||||
</Text>
|
||||
<TouchableOpacity onPress={this.checkUpdate}>
|
||||
<Text style={styles.instructions}>点击这里检查更新</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={{marginTop: 15}}
|
||||
onLongPress={() => {
|
||||
this.setState({showTestConsole: true});
|
||||
}}>
|
||||
<Text style={styles.instructions}>
|
||||
react-native-update版本:{cInfo.pushy}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TestConsole visible={showTestConsole} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
2
LICENSE
2
LICENSE
@@ -2,7 +2,7 @@ Update Plugin for React Native
|
||||
|
||||
Powered by ReactNative.cn
|
||||
|
||||
Copyright (c) Hangzhou Erica Network Technology Co., Ltd.
|
||||
Copyright (c) Wuhan Charmlot Network Technology Co., Ltd.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
17
README.md
17
README.md
@@ -1,18 +1,19 @@
|
||||
# react-native-update [](http://badge.fury.io/js/react-native-update)
|
||||
|
||||
本组件是面向 React Native 提供热更新功能的组件,请结合[Update 服务](https://update.reactnative.cn/)使用。
|
||||
本组件是面向 React Native 提供热更新功能的组件,详情请访问我们的官方网站 <https://pushy.reactnative.cn>。
|
||||
|
||||
### 快速开始
|
||||
|
||||
请查看[文档](https://reactnativecn.github.io/react-native-pushy)
|
||||
请查看[文档](https://pushy.reactnative.cn/docs/getting-started.html)
|
||||
|
||||
### 优势
|
||||
|
||||
1. 命令行工具&网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
||||
2. 基于 bsdiff 算法创建的**超小更新包**,通常版本迭代后在 1-10KB 之间,避免数百 KB 的流量消耗。
|
||||
3. 支持崩溃回滚,安全可靠。
|
||||
4. meta 信息及开放 API,提供更高扩展性。
|
||||
5. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
||||
1. 基于阿里云高速 CDN 分发,对比其他服务器在国外的热更新服务,分发更稳定,更新成功率极高。
|
||||
2. 基于 bsdiff/hdiff 算法创建的**超小更新包**,通常版本迭代后在 1-10KB 之间,避免数百 KB 的流量消耗。
|
||||
3. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
||||
4. 命令行工具&网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
||||
5. 支持崩溃回滚,安全可靠。
|
||||
6. meta 信息及开放 API,提供更高扩展性。
|
||||
|
||||
### 本地开发
|
||||
|
||||
@@ -29,4 +30,4 @@ $ yarn start
|
||||
|
||||
本组件由[React Native 中文网](https://reactnative.cn/)独家发布,如有定制需求可以[联系我们](https://reactnative.cn/about.html#content)。
|
||||
|
||||
关于此插件发现任何问题,可以前往[Issues](https://github.com/reactnativecn/react-native-pushy/issues)或者[中文社区](http://bbs.reactnative.cn/category/7)发帖提问。
|
||||
关于此插件发现任何问题,可以前往[Issues](https://github.com/reactnativecn/react-native-pushy/issues)发帖提问。
|
||||
|
@@ -3,15 +3,16 @@ LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := rnupdate
|
||||
|
||||
Hdp_Files := \
|
||||
hpatch.c \
|
||||
HDiffPatch/libHDiffPatch/HPatch/patch.c \
|
||||
HDiffPatch/file_for_patch.c \
|
||||
lzma/C/LzmaDec.c \
|
||||
lzma/C/Lzma2Dec.c
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
DownloadTask.c \
|
||||
blocksort.c \
|
||||
bspatch.c \
|
||||
bzlib.c \
|
||||
crctable.c \
|
||||
compress.c \
|
||||
decompress.c \
|
||||
huffman.c \
|
||||
randtable.c
|
||||
$(Hdp_Files)
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
7
android/jni/Application.mk
Normal file
7
android/jni/Application.mk
Normal file
@@ -0,0 +1,7 @@
|
||||
APP_PLATFORM := android-16
|
||||
APP_CFLAGS += -Wno-error=format-security
|
||||
APP_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
|
||||
APP_CFLAGS += -ffunction-sections -fdata-sections
|
||||
APP_LDFLAGS += -Wl,--gc-sections
|
||||
APP_BUILD_SCRIPT := Android.mk
|
||||
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
|
@@ -3,109 +3,54 @@
|
||||
//
|
||||
|
||||
#include "cn_reactnative_modules_update_DownloadTask.h"
|
||||
#include <stdlib.h>
|
||||
#include "bzlib.h"
|
||||
#include "bspatch.h"
|
||||
#include <android/log.h>
|
||||
|
||||
static int64_t offtin(uint8_t *buf)
|
||||
{
|
||||
int64_t y;
|
||||
#include "hpatch.h"
|
||||
#define _check(v,errInfo) do{ if (!(v)) { _isError=hpatch_TRUE; _errInfo=errInfo; goto _clear; } }while(0)
|
||||
|
||||
y=buf[7]&0x7F;
|
||||
y=y*256;y+=buf[6];
|
||||
y=y*256;y+=buf[5];
|
||||
y=y*256;y+=buf[4];
|
||||
y=y*256;y+=buf[3];
|
||||
y=y*256;y+=buf[2];
|
||||
y=y*256;y+=buf[1];
|
||||
y=y*256;y+=buf[0];
|
||||
|
||||
if(buf[7]&0x80) y=-y;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
const size_t BUFFER_SIZE = 4096;
|
||||
|
||||
static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length)
|
||||
{
|
||||
int n;
|
||||
int bz2err;
|
||||
bz_stream* zip;
|
||||
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
zip = (bz_stream*)stream->opaque;
|
||||
zip->next_out = (char*)buffer;
|
||||
zip->avail_out = length;
|
||||
|
||||
int bz2Ret = BZ2_bzDecompress(zip);
|
||||
|
||||
if (bz2Ret != BZ_OK && (bz2Ret != BZ_STREAM_END || zip->avail_out > 0))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_bsdiffPatch
|
||||
JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_hdiffPatch
|
||||
(JNIEnv *env, jobject self, jbyteArray origin, jbyteArray patch){
|
||||
jclass newExcCls;
|
||||
jbyte* outPtr;
|
||||
struct bspatch_stream stream;
|
||||
bz_stream zip;
|
||||
hpatch_BOOL _isError=hpatch_FALSE;
|
||||
const char* _errInfo="";
|
||||
|
||||
jbyte* originPtr = (*env)->GetByteArrayElements(env, origin, NULL);
|
||||
size_t originLength = (*env)->GetArrayLength(env, origin);
|
||||
jbyte* patchPtr = (*env)->GetByteArrayElements(env, patch, NULL);
|
||||
size_t patchLength = (*env)->GetArrayLength(env, patch);
|
||||
jbyteArray ret = NULL;
|
||||
jbyte* outPtr = NULL;
|
||||
size_t newsize = 0;
|
||||
hpatch_singleCompressedDiffInfo patInfo;
|
||||
|
||||
if (patchLength < 32) {
|
||||
newExcCls = (*env)->FindClass(env,"java/lang/Error");
|
||||
if (newExcCls != NULL) /* Unable to find the new exception class, give up. */
|
||||
(*env)->ThrowNew(env,newExcCls, "Corrupt patch");
|
||||
(*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT);
|
||||
(*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT);
|
||||
return NULL;
|
||||
_check(((originLength==0)||originPtr) && patchPtr && (patchLength>0),"Corrupt patch");
|
||||
_check(kHPatch_ok==hpatch_getInfo_by_mem(&patInfo,(const uint8_t*)patchPtr,patchLength),"Error info in hpatch");
|
||||
_check(originLength==patInfo.oldDataSize,"Error oldDataSize in hpatch");
|
||||
newsize=(size_t)patInfo.newDataSize;
|
||||
if (sizeof(size_t)!=sizeof(hpatch_StreamPos_t))
|
||||
_check(newsize==patInfo.newDataSize,"Error newDataSize in hpatch");
|
||||
|
||||
ret = (*env)->NewByteArray(env,newsize);
|
||||
_check(ret,"Error JNIEnv::NewByteArray()");
|
||||
if (newsize>0) {
|
||||
outPtr = (*env)->GetByteArrayElements(env, ret, NULL);
|
||||
_check(outPtr,"Corrupt JNIEnv::GetByteArrayElements");
|
||||
}
|
||||
int64_t newsize=offtin((uint8_t*)patchPtr + 16);
|
||||
if (memcmp(patchPtr, "ENDSLEY/BSDIFF43", 16) != 0 || newsize<0) {
|
||||
|
||||
_check(kHPatch_ok==hpatch_by_mem((const uint8_t*)originPtr,originLength,(uint8_t*)outPtr,newsize,
|
||||
(const uint8_t*)patchPtr,patchLength,&patInfo),"hpacth");
|
||||
|
||||
_clear:
|
||||
if (outPtr) (*env)->ReleaseByteArrayElements(env, ret, outPtr, (_isError?JNI_ABORT:0));
|
||||
if (originPtr) (*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT);
|
||||
if (patchPtr) (*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT);
|
||||
if (_isError){
|
||||
jclass newExcCls = NULL;
|
||||
if (ret){
|
||||
(*env)->DeleteLocalRef(env, ret);
|
||||
ret = NULL;
|
||||
}
|
||||
newExcCls = (*env)->FindClass(env, "java/lang/Error");
|
||||
if (newExcCls != NULL) /* Unable to find the new exception class, give up. */
|
||||
(*env)->ThrowNew(env, newExcCls, "Corrupt patch");
|
||||
(*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT);
|
||||
(*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT);
|
||||
return NULL;
|
||||
if (newExcCls != NULL) // Unable to find the new exception class, give up.
|
||||
(*env)->ThrowNew(env, newExcCls, _errInfo);
|
||||
}
|
||||
ret = (*env)->NewByteArray(env, newsize);
|
||||
if (ret == NULL) {
|
||||
return NULL; // out of memory error thrown
|
||||
}
|
||||
outPtr = (*env)->GetByteArrayElements(env, ret, NULL);
|
||||
|
||||
zip.bzalloc = NULL;
|
||||
zip.bzfree = NULL;
|
||||
zip.opaque = NULL;
|
||||
BZ2_bzDecompressInit(&zip, 0, 1);
|
||||
|
||||
zip.next_in = (char*)patchPtr + 32;
|
||||
zip.avail_in = patchLength - 32;
|
||||
|
||||
stream.read = bz2_read;
|
||||
stream.opaque = &zip;
|
||||
if (bspatch((const uint8_t*)originPtr, originLength, (uint8_t*)outPtr, newsize, &stream)) {
|
||||
newExcCls = (*env)->FindClass(env, "java/lang/Error");
|
||||
if (newExcCls != NULL) /* Unable to find the new exception class, give up. */
|
||||
(*env)->ThrowNew(env, newExcCls, "bspatch");
|
||||
}
|
||||
|
||||
BZ2_bzDecompressEnd(&zip);
|
||||
|
||||
(*env)->ReleaseByteArrayElements(env, ret, outPtr, 0);
|
||||
(*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT);
|
||||
(*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
1
android/jni/HDiffPatch
Submodule
1
android/jni/HDiffPatch
Submodule
Submodule android/jni/HDiffPatch added at eb959d671c
File diff suppressed because it is too large
Load Diff
@@ -1,187 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2003-2005 Colin Percival
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "bspatch.h"
|
||||
|
||||
static int64_t offtin(uint8_t *buf)
|
||||
{
|
||||
int64_t y;
|
||||
|
||||
y=buf[7]&0x7F;
|
||||
y=y*256;y+=buf[6];
|
||||
y=y*256;y+=buf[5];
|
||||
y=y*256;y+=buf[4];
|
||||
y=y*256;y+=buf[3];
|
||||
y=y*256;y+=buf[2];
|
||||
y=y*256;y+=buf[1];
|
||||
y=y*256;y+=buf[0];
|
||||
|
||||
if(buf[7]&0x80) y=-y;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
int64_t oldpos,newpos;
|
||||
int64_t ctrl[3];
|
||||
int64_t i;
|
||||
|
||||
oldpos=0;newpos=0;
|
||||
while(newpos<newsize) {
|
||||
/* Read control data */
|
||||
for(i=0;i<=2;i++) {
|
||||
if (stream->read(stream, buf, 8))
|
||||
return -1;
|
||||
ctrl[i]=offtin(buf);
|
||||
};
|
||||
|
||||
/* Sanity-check */
|
||||
if(newpos+ctrl[0]>newsize)
|
||||
return -1;
|
||||
|
||||
/* Read diff string */
|
||||
if (stream->read(stream, new + newpos, ctrl[0]))
|
||||
return -1;
|
||||
|
||||
/* Add old data to diff string */
|
||||
for(i=0;i<ctrl[0];i++)
|
||||
if((oldpos+i>=0) && (oldpos+i<oldsize))
|
||||
new[newpos+i]+=old[oldpos+i];
|
||||
|
||||
/* Adjust pointers */
|
||||
newpos+=ctrl[0];
|
||||
oldpos+=ctrl[0];
|
||||
|
||||
/* Sanity-check */
|
||||
if(newpos+ctrl[1]>newsize)
|
||||
return -1;
|
||||
|
||||
/* Read extra string */
|
||||
if (stream->read(stream, new + newpos, ctrl[1]))
|
||||
return -1;
|
||||
|
||||
/* Adjust pointers */
|
||||
newpos+=ctrl[1];
|
||||
oldpos+=ctrl[2];
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(BSPATCH_EXECUTABLE)
|
||||
|
||||
#include <bzlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length)
|
||||
{
|
||||
int n;
|
||||
int bz2err;
|
||||
BZFILE* bz2;
|
||||
|
||||
bz2 = (BZFILE*)stream->opaque;
|
||||
n = BZ2_bzRead(&bz2err, bz2, buffer, length);
|
||||
if (n != length)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc,char * argv[])
|
||||
{
|
||||
FILE * f;
|
||||
int fd;
|
||||
int bz2err;
|
||||
uint8_t header[24];
|
||||
uint8_t *old, *new;
|
||||
int64_t oldsize, newsize;
|
||||
BZFILE* bz2;
|
||||
struct bspatch_stream stream;
|
||||
|
||||
if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
|
||||
|
||||
/* Open patch file */
|
||||
if ((f = fopen(argv[3], "r")) == NULL)
|
||||
err(1, "fopen(%s)", argv[3]);
|
||||
|
||||
/* Read header */
|
||||
if (fread(header, 1, 24, f) != 24) {
|
||||
if (feof(f))
|
||||
errx(1, "Corrupt patch\n");
|
||||
err(1, "fread(%s)", argv[3]);
|
||||
}
|
||||
|
||||
/* Check for appropriate magic */
|
||||
if (memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0)
|
||||
errx(1, "Corrupt patch\n");
|
||||
|
||||
/* Read lengths from header */
|
||||
newsize=offtin(header+16);
|
||||
if(newsize<0)
|
||||
errx(1,"Corrupt patch\n");
|
||||
|
||||
/* Close patch file and re-open it via libbzip2 at the right places */
|
||||
if(((fd=open(argv[1],O_RDONLY,0))<0) ||
|
||||
((oldsize=lseek(fd,0,SEEK_END))==-1) ||
|
||||
((old=malloc(oldsize+1))==NULL) ||
|
||||
(lseek(fd,0,SEEK_SET)!=0) ||
|
||||
(read(fd,old,oldsize)!=oldsize) ||
|
||||
(close(fd)==-1)) err(1,"%s",argv[1]);
|
||||
if((new=malloc(newsize+1))==NULL) err(1,NULL);
|
||||
|
||||
if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 0, NULL, 0)))
|
||||
errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err);
|
||||
|
||||
stream.read = bz2_read;
|
||||
stream.opaque = bz2;
|
||||
if (bspatch(old, oldsize, new, newsize, &stream))
|
||||
errx(1, "bspatch");
|
||||
|
||||
/* Clean up the bzip2 reads */
|
||||
BZ2_bzReadClose(&bz2err, bz2);
|
||||
fclose(f);
|
||||
|
||||
/* Write the new file */
|
||||
if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
|
||||
(write(fd,new,newsize)!=newsize) || (close(fd)==-1))
|
||||
err(1,"%s",argv[2]);
|
||||
|
||||
free(new);
|
||||
free(old);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,41 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2003-2005 Colin Percival
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BSPATCH_H
|
||||
# define BSPATCH_H
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
struct bspatch_stream
|
||||
{
|
||||
void* opaque;
|
||||
int (*read)(const struct bspatch_stream* stream, void* buffer, int length);
|
||||
};
|
||||
|
||||
int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* newBuf, int64_t newsize, struct bspatch_stream* stream);
|
||||
|
||||
#endif
|
1573
android/jni/bzlib.c
1573
android/jni/bzlib.c
File diff suppressed because it is too large
Load Diff
@@ -1,282 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Public header file for the library. ---*/
|
||||
/*--- bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_H
|
||||
#define _BZLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BZ_RUN 0
|
||||
#define BZ_FLUSH 1
|
||||
#define BZ_FINISH 2
|
||||
|
||||
#define BZ_OK 0
|
||||
#define BZ_RUN_OK 1
|
||||
#define BZ_FLUSH_OK 2
|
||||
#define BZ_FINISH_OK 3
|
||||
#define BZ_STREAM_END 4
|
||||
#define BZ_SEQUENCE_ERROR (-1)
|
||||
#define BZ_PARAM_ERROR (-2)
|
||||
#define BZ_MEM_ERROR (-3)
|
||||
#define BZ_DATA_ERROR (-4)
|
||||
#define BZ_DATA_ERROR_MAGIC (-5)
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
void *(*bzalloc)(void *,int,int);
|
||||
void (*bzfree)(void *,void *);
|
||||
void *opaque;
|
||||
}
|
||||
bz_stream;
|
||||
|
||||
|
||||
#ifndef BZ_IMPORT
|
||||
#define BZ_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
/* Need a definitition for FILE */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# ifdef small
|
||||
/* windows.h define small to char */
|
||||
# undef small
|
||||
# endif
|
||||
# ifdef BZ_EXPORT
|
||||
# define BZ_API(func) WINAPI func
|
||||
# define BZ_EXTERN extern
|
||||
# else
|
||||
/* import windows dll dynamically */
|
||||
# define BZ_API(func) (WINAPI * func)
|
||||
# define BZ_EXTERN
|
||||
# endif
|
||||
#else
|
||||
# define BZ_API(func) func
|
||||
# define BZ_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm,
|
||||
int verbosity,
|
||||
int small
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*-- High(er) level library functions --*/
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#define BZ_MAX_UNUSED 5000
|
||||
|
||||
typedef void BZFILE;
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
int small,
|
||||
void* unused,
|
||||
int nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
int* nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzRead) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Utility functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int small,
|
||||
int verbosity
|
||||
);
|
||||
|
||||
|
||||
/*--
|
||||
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
|
||||
to support better zlib compatibility.
|
||||
This code is not _officially_ part of libbzip2 (yet);
|
||||
I haven't tested it, documented it, or considered the
|
||||
threading-safeness of it.
|
||||
If this code breaks, please contact both Yoshioka and me.
|
||||
--*/
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
|
||||
void
|
||||
);
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
|
||||
const char *path,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
|
||||
int fd,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzread) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzflush) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzclose) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
|
||||
BZFILE *b,
|
||||
int *errnum
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
@@ -1,509 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Private header file for the library. ---*/
|
||||
/*--- bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_PRIVATE_H
|
||||
#define _BZLIB_PRIVATE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "1.0.6, 6-Sept-2010"
|
||||
|
||||
typedef char Char;
|
||||
typedef unsigned char Bool;
|
||||
typedef unsigned char UChar;
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#define True ((Bool)1)
|
||||
#define False ((Bool)0)
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __inline__ /* */
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
|
||||
extern void BZ2_bz__AssertH__fail ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
|
||||
|
||||
#if BZ_DEBUG
|
||||
#define AssertD(cond,msg) \
|
||||
{ if (!(cond)) { \
|
||||
fprintf ( stderr, \
|
||||
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
|
||||
exit(1); \
|
||||
}}
|
||||
#else
|
||||
#define AssertD(cond,msg) /* */
|
||||
#endif
|
||||
|
||||
#define VPrintf0(zf) \
|
||||
fprintf(stderr,zf)
|
||||
#define VPrintf1(zf,za1) \
|
||||
fprintf(stderr,zf,za1)
|
||||
#define VPrintf2(zf,za1,za2) \
|
||||
fprintf(stderr,zf,za1,za2)
|
||||
#define VPrintf3(zf,za1,za2,za3) \
|
||||
fprintf(stderr,zf,za1,za2,za3)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4,za5)
|
||||
|
||||
#else
|
||||
|
||||
extern void bz_internal_error ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) bz_internal_error ( errcode ); }
|
||||
#define AssertD(cond,msg) do { } while (0)
|
||||
#define VPrintf0(zf) do { } while (0)
|
||||
#define VPrintf1(zf,za1) do { } while (0)
|
||||
#define VPrintf2(zf,za1,za2) do { } while (0)
|
||||
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
|
||||
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
|
||||
|
||||
|
||||
/*-- Header bytes. --*/
|
||||
|
||||
#define BZ_HDR_B 0x42 /* 'B' */
|
||||
#define BZ_HDR_Z 0x5a /* 'Z' */
|
||||
#define BZ_HDR_h 0x68 /* 'h' */
|
||||
#define BZ_HDR_0 0x30 /* '0' */
|
||||
|
||||
/*-- Constants for the back end. --*/
|
||||
|
||||
#define BZ_MAX_ALPHA_SIZE 258
|
||||
#define BZ_MAX_CODE_LEN 23
|
||||
|
||||
#define BZ_RUNA 0
|
||||
#define BZ_RUNB 1
|
||||
|
||||
#define BZ_N_GROUPS 6
|
||||
#define BZ_G_SIZE 50
|
||||
#define BZ_N_ITERS 4
|
||||
|
||||
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for randomising repetitive blocks. --*/
|
||||
|
||||
extern Int32 BZ2_rNums[512];
|
||||
|
||||
#define BZ_RAND_DECLS \
|
||||
Int32 rNToGo; \
|
||||
Int32 rTPos \
|
||||
|
||||
#define BZ_RAND_INIT_MASK \
|
||||
s->rNToGo = 0; \
|
||||
s->rTPos = 0 \
|
||||
|
||||
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
|
||||
|
||||
#define BZ_RAND_UPD_MASK \
|
||||
if (s->rNToGo == 0) { \
|
||||
s->rNToGo = BZ2_rNums[s->rTPos]; \
|
||||
s->rTPos++; \
|
||||
if (s->rTPos == 512) s->rTPos = 0; \
|
||||
} \
|
||||
s->rNToGo--;
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for doing CRCs. --*/
|
||||
|
||||
extern UInt32 BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = 0xffffffffL; \
|
||||
}
|
||||
|
||||
#define BZ_FINALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = ~(crcVar); \
|
||||
}
|
||||
|
||||
#define BZ_UPDATE_CRC(crcVar,cha) \
|
||||
{ \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-- States and modes for compression. --*/
|
||||
|
||||
#define BZ_M_IDLE 1
|
||||
#define BZ_M_RUNNING 2
|
||||
#define BZ_M_FLUSHING 3
|
||||
#define BZ_M_FINISHING 4
|
||||
|
||||
#define BZ_S_OUTPUT 1
|
||||
#define BZ_S_INPUT 2
|
||||
|
||||
#define BZ_N_RADIX 2
|
||||
#define BZ_N_QSORT 12
|
||||
#define BZ_N_SHELL 18
|
||||
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
|
||||
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the compression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* mode this stream is in, and whether inputting */
|
||||
/* or outputting data */
|
||||
Int32 mode;
|
||||
Int32 state;
|
||||
|
||||
/* remembers avail_in when flush/finish requested */
|
||||
UInt32 avail_in_expect;
|
||||
|
||||
/* for doing the block sorting */
|
||||
UInt32* arr1;
|
||||
UInt32* arr2;
|
||||
UInt32* ftab;
|
||||
Int32 origPtr;
|
||||
|
||||
/* aliases for arr1 and arr2 */
|
||||
UInt32* ptr;
|
||||
UChar* block;
|
||||
UInt16* mtfv;
|
||||
UChar* zbits;
|
||||
|
||||
/* for deciding when to use the fallback sorting algorithm */
|
||||
Int32 workFactor;
|
||||
|
||||
/* run-length-encoding of the input */
|
||||
UInt32 state_in_ch;
|
||||
Int32 state_in_len;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* input and output limits and current posns */
|
||||
Int32 nblock;
|
||||
Int32 nblockMAX;
|
||||
Int32 numZ;
|
||||
Int32 state_out_pos;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
UChar unseqToSeq[256];
|
||||
|
||||
/* the buffer for bit stream creation */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* block and combined CRCs */
|
||||
UInt32 blockCRC;
|
||||
UInt32 combinedCRC;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 verbosity;
|
||||
Int32 blockNo;
|
||||
Int32 blockSize100k;
|
||||
|
||||
/* stuff for coding the MTF values */
|
||||
Int32 nMTF;
|
||||
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
/* second dimension: only 3 needed; 4 makes index calculations faster */
|
||||
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
|
||||
|
||||
}
|
||||
EState;
|
||||
|
||||
|
||||
|
||||
/*-- externs for compression. --*/
|
||||
|
||||
extern void
|
||||
BZ2_blockSort ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_compressBlock ( EState*, Bool );
|
||||
|
||||
extern void
|
||||
BZ2_bsInitWrite ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
|
||||
|
||||
extern void
|
||||
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
|
||||
|
||||
|
||||
|
||||
/*-- states for decompression. --*/
|
||||
|
||||
#define BZ_X_IDLE 1
|
||||
#define BZ_X_OUTPUT 2
|
||||
|
||||
#define BZ_X_MAGIC_1 10
|
||||
#define BZ_X_MAGIC_2 11
|
||||
#define BZ_X_MAGIC_3 12
|
||||
#define BZ_X_MAGIC_4 13
|
||||
#define BZ_X_BLKHDR_1 14
|
||||
#define BZ_X_BLKHDR_2 15
|
||||
#define BZ_X_BLKHDR_3 16
|
||||
#define BZ_X_BLKHDR_4 17
|
||||
#define BZ_X_BLKHDR_5 18
|
||||
#define BZ_X_BLKHDR_6 19
|
||||
#define BZ_X_BCRC_1 20
|
||||
#define BZ_X_BCRC_2 21
|
||||
#define BZ_X_BCRC_3 22
|
||||
#define BZ_X_BCRC_4 23
|
||||
#define BZ_X_RANDBIT 24
|
||||
#define BZ_X_ORIGPTR_1 25
|
||||
#define BZ_X_ORIGPTR_2 26
|
||||
#define BZ_X_ORIGPTR_3 27
|
||||
#define BZ_X_MAPPING_1 28
|
||||
#define BZ_X_MAPPING_2 29
|
||||
#define BZ_X_SELECTOR_1 30
|
||||
#define BZ_X_SELECTOR_2 31
|
||||
#define BZ_X_SELECTOR_3 32
|
||||
#define BZ_X_CODING_1 33
|
||||
#define BZ_X_CODING_2 34
|
||||
#define BZ_X_CODING_3 35
|
||||
#define BZ_X_MTF_1 36
|
||||
#define BZ_X_MTF_2 37
|
||||
#define BZ_X_MTF_3 38
|
||||
#define BZ_X_MTF_4 39
|
||||
#define BZ_X_MTF_5 40
|
||||
#define BZ_X_MTF_6 41
|
||||
#define BZ_X_ENDHDR_2 42
|
||||
#define BZ_X_ENDHDR_3 43
|
||||
#define BZ_X_ENDHDR_4 44
|
||||
#define BZ_X_ENDHDR_5 45
|
||||
#define BZ_X_ENDHDR_6 46
|
||||
#define BZ_X_CCRC_1 47
|
||||
#define BZ_X_CCRC_2 48
|
||||
#define BZ_X_CCRC_3 49
|
||||
#define BZ_X_CCRC_4 50
|
||||
|
||||
|
||||
|
||||
/*-- Constants for the fast MTF decoder. --*/
|
||||
|
||||
#define MTFA_SIZE 4096
|
||||
#define MTFL_SIZE 16
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the decompression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* state indicator for this stream */
|
||||
Int32 state;
|
||||
|
||||
/* for doing the final run-length decoding */
|
||||
UChar state_out_ch;
|
||||
Int32 state_out_len;
|
||||
Bool blockRandomised;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* the buffer for bit stream reading */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 blockSize100k;
|
||||
Bool smallDecompress;
|
||||
Int32 currBlockNo;
|
||||
Int32 verbosity;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform */
|
||||
Int32 origPtr;
|
||||
UInt32 tPos;
|
||||
Int32 k0;
|
||||
Int32 unzftab[256];
|
||||
Int32 nblock_used;
|
||||
Int32 cftab[257];
|
||||
Int32 cftabCopy[257];
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (FAST) */
|
||||
UInt32 *tt;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (SMALL) */
|
||||
UInt16 *ll16;
|
||||
UChar *ll4;
|
||||
|
||||
/* stored and calculated CRCs */
|
||||
UInt32 storedBlockCRC;
|
||||
UInt32 storedCombinedCRC;
|
||||
UInt32 calculatedBlockCRC;
|
||||
UInt32 calculatedCombinedCRC;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
Bool inUse16[16];
|
||||
UChar seqToUnseq[256];
|
||||
|
||||
/* for decoding the MTF values */
|
||||
UChar mtfa [MTFA_SIZE];
|
||||
Int32 mtfbase[256 / MTFL_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
|
||||
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 minLens[BZ_N_GROUPS];
|
||||
|
||||
/* save area for scalars in the main decompress code */
|
||||
Int32 save_i;
|
||||
Int32 save_j;
|
||||
Int32 save_t;
|
||||
Int32 save_alphaSize;
|
||||
Int32 save_nGroups;
|
||||
Int32 save_nSelectors;
|
||||
Int32 save_EOB;
|
||||
Int32 save_groupNo;
|
||||
Int32 save_groupPos;
|
||||
Int32 save_nextSym;
|
||||
Int32 save_nblockMAX;
|
||||
Int32 save_nblock;
|
||||
Int32 save_es;
|
||||
Int32 save_N;
|
||||
Int32 save_curr;
|
||||
Int32 save_zt;
|
||||
Int32 save_zn;
|
||||
Int32 save_zvec;
|
||||
Int32 save_zj;
|
||||
Int32 save_gSel;
|
||||
Int32 save_gMinlen;
|
||||
Int32* save_gLimit;
|
||||
Int32* save_gBase;
|
||||
Int32* save_gPerm;
|
||||
|
||||
}
|
||||
DState;
|
||||
|
||||
|
||||
|
||||
/*-- Macros for decompression. --*/
|
||||
|
||||
#define BZ_GET_FAST(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
s->tPos = s->tt[s->tPos]; \
|
||||
cccc = (UChar)(s->tPos & 0xff); \
|
||||
s->tPos >>= 8;
|
||||
|
||||
#define BZ_GET_FAST_C(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
|
||||
c_tPos = c_tt[c_tPos]; \
|
||||
cccc = (UChar)(c_tPos & 0xff); \
|
||||
c_tPos >>= 8;
|
||||
|
||||
#define SET_LL4(i,n) \
|
||||
{ if (((i) & 0x1) == 0) \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
|
||||
}
|
||||
|
||||
#define GET_LL4(i) \
|
||||
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
|
||||
|
||||
#define SET_LL(i,n) \
|
||||
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
|
||||
SET_LL4(i, n >> 16); \
|
||||
}
|
||||
|
||||
#define GET_LL(i) \
|
||||
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
|
||||
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
extern Int32
|
||||
BZ2_indexIntoF ( Int32, Int32* );
|
||||
|
||||
extern Int32
|
||||
BZ2_decompress ( DState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
|
||||
|
||||
#ifdef BZ_NO_STDIO
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
@@ -9,10 +9,10 @@ extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: cn_reactnative_modules_update_DownloadTask
|
||||
* Method: bsdiffPatch
|
||||
* Method: hdiffPatch
|
||||
* Signature: ([B[B)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_bsdiffPatch
|
||||
JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_hdiffPatch
|
||||
(JNIEnv *, jclass, jbyteArray, jbyteArray);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -1,672 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Compression machinery (not incl block sorting) ---*/
|
||||
/*--- compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
/* CHANGES
|
||||
0.9.0 -- original version.
|
||||
0.9.0a/b -- no changes in this file.
|
||||
0.9.0c -- changed setting of nGroups in sendMTFValues()
|
||||
so as to do a bit better on small files
|
||||
*/
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- Bit stream I/O ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_bsInitWrite ( EState* s )
|
||||
{
|
||||
s->bsLive = 0;
|
||||
s->bsBuff = 0;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsFinishWrite ( EState* s )
|
||||
{
|
||||
while (s->bsLive > 0) {
|
||||
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
|
||||
s->numZ++;
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define bsNEEDW(nz) \
|
||||
{ \
|
||||
while (s->bsLive >= 8) { \
|
||||
s->zbits[s->numZ] \
|
||||
= (UChar)(s->bsBuff >> 24); \
|
||||
s->numZ++; \
|
||||
s->bsBuff <<= 8; \
|
||||
s->bsLive -= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
__inline__
|
||||
void bsW ( EState* s, Int32 n, UInt32 v )
|
||||
{
|
||||
bsNEEDW ( n );
|
||||
s->bsBuff |= (v << (32 - s->bsLive - n));
|
||||
s->bsLive += n;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsPutUInt32 ( EState* s, UInt32 u )
|
||||
{
|
||||
bsW ( s, 8, (u >> 24) & 0xffL );
|
||||
bsW ( s, 8, (u >> 16) & 0xffL );
|
||||
bsW ( s, 8, (u >> 8) & 0xffL );
|
||||
bsW ( s, 8, u & 0xffL );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsPutUChar ( EState* s, UChar c )
|
||||
{
|
||||
bsW( s, 8, (UInt32)c );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- The back end proper ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_e ( EState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->unseqToSeq[i] = s->nInUse;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void generateMTFValues ( EState* s )
|
||||
{
|
||||
UChar yy[256];
|
||||
Int32 i, j;
|
||||
Int32 zPend;
|
||||
Int32 wr;
|
||||
Int32 EOB;
|
||||
|
||||
/*
|
||||
After sorting (eg, here),
|
||||
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
|
||||
and
|
||||
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
|
||||
holds the original block data.
|
||||
|
||||
The first thing to do is generate the MTF values,
|
||||
and put them in
|
||||
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
|
||||
Because there are strictly fewer or equal MTF values
|
||||
than block values, ptr values in this area are overwritten
|
||||
with MTF values only when they are no longer needed.
|
||||
|
||||
The final compressed bitstream is generated into the
|
||||
area starting at
|
||||
(UChar*) (&((UChar*)s->arr2)[s->nblock])
|
||||
|
||||
These storage aliases are set up in bzCompressInit(),
|
||||
except for the last one, which is arranged in
|
||||
compressBlock().
|
||||
*/
|
||||
UInt32* ptr = s->ptr;
|
||||
UChar* block = s->block;
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
makeMaps_e ( s );
|
||||
EOB = s->nInUse+1;
|
||||
|
||||
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
|
||||
|
||||
wr = 0;
|
||||
zPend = 0;
|
||||
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
|
||||
|
||||
for (i = 0; i < s->nblock; i++) {
|
||||
UChar ll_i;
|
||||
AssertD ( wr <= i, "generateMTFValues(1)" );
|
||||
j = ptr[i]-1; if (j < 0) j += s->nblock;
|
||||
ll_i = s->unseqToSeq[block[j]];
|
||||
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
|
||||
|
||||
if (yy[0] == ll_i) {
|
||||
zPend++;
|
||||
} else {
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
while (True) {
|
||||
if (zPend & 1) {
|
||||
mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
{
|
||||
register UChar rtmp;
|
||||
register UChar* ryy_j;
|
||||
register UChar rll_i;
|
||||
rtmp = yy[1];
|
||||
yy[1] = yy[0];
|
||||
ryy_j = &(yy[1]);
|
||||
rll_i = ll_i;
|
||||
while ( rll_i != rtmp ) {
|
||||
register UChar rtmp2;
|
||||
ryy_j++;
|
||||
rtmp2 = rtmp;
|
||||
rtmp = *ryy_j;
|
||||
*ryy_j = rtmp2;
|
||||
};
|
||||
yy[0] = rtmp;
|
||||
j = ryy_j - &(yy[0]);
|
||||
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
while (True) {
|
||||
if (zPend & 1) {
|
||||
mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
|
||||
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
|
||||
|
||||
s->nMTF = wr;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define BZ_LESSER_ICOST 0
|
||||
#define BZ_GREATER_ICOST 15
|
||||
|
||||
static
|
||||
void sendMTFValues ( EState* s )
|
||||
{
|
||||
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
|
||||
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
|
||||
Int32 nGroups, nBytes;
|
||||
|
||||
/*--
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
is a global since the decoder also needs it.
|
||||
|
||||
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
are also globals only used in this proc.
|
||||
Made global to keep stack frame size small.
|
||||
--*/
|
||||
|
||||
|
||||
UInt16 cost[BZ_N_GROUPS];
|
||||
Int32 fave[BZ_N_GROUPS];
|
||||
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
|
||||
"%d+2 syms in use\n",
|
||||
s->nblock, s->nMTF, s->nInUse );
|
||||
|
||||
alphaSize = s->nInUse+2;
|
||||
for (t = 0; t < BZ_N_GROUPS; t++)
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->len[t][v] = BZ_GREATER_ICOST;
|
||||
|
||||
/*--- Decide how many coding tables to use ---*/
|
||||
AssertH ( s->nMTF > 0, 3001 );
|
||||
if (s->nMTF < 200) nGroups = 2; else
|
||||
if (s->nMTF < 600) nGroups = 3; else
|
||||
if (s->nMTF < 1200) nGroups = 4; else
|
||||
if (s->nMTF < 2400) nGroups = 5; else
|
||||
nGroups = 6;
|
||||
|
||||
/*--- Generate an initial set of coding tables ---*/
|
||||
{
|
||||
Int32 nPart, remF, tFreq, aFreq;
|
||||
|
||||
nPart = nGroups;
|
||||
remF = s->nMTF;
|
||||
gs = 0;
|
||||
while (nPart > 0) {
|
||||
tFreq = remF / nPart;
|
||||
ge = gs-1;
|
||||
aFreq = 0;
|
||||
while (aFreq < tFreq && ge < alphaSize-1) {
|
||||
ge++;
|
||||
aFreq += s->mtfFreq[ge];
|
||||
}
|
||||
|
||||
if (ge > gs
|
||||
&& nPart != nGroups && nPart != 1
|
||||
&& ((nGroups-nPart) % 2 == 1)) {
|
||||
aFreq -= s->mtfFreq[ge];
|
||||
ge--;
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf5( " initial group %d, [%d .. %d], "
|
||||
"has %d syms (%4.1f%%)\n",
|
||||
nPart, gs, ge, aFreq,
|
||||
(100.0 * (float)aFreq) / (float)(s->nMTF) );
|
||||
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
if (v >= gs && v <= ge)
|
||||
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
|
||||
s->len[nPart-1][v] = BZ_GREATER_ICOST;
|
||||
|
||||
nPart--;
|
||||
gs = ge+1;
|
||||
remF -= aFreq;
|
||||
}
|
||||
}
|
||||
|
||||
/*---
|
||||
Iterate up to BZ_N_ITERS times to improve the tables.
|
||||
---*/
|
||||
for (iter = 0; iter < BZ_N_ITERS; iter++) {
|
||||
|
||||
for (t = 0; t < nGroups; t++) fave[t] = 0;
|
||||
|
||||
for (t = 0; t < nGroups; t++)
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->rfreq[t][v] = 0;
|
||||
|
||||
/*---
|
||||
Set up an auxiliary length table which is used to fast-track
|
||||
the common case (nGroups == 6).
|
||||
---*/
|
||||
if (nGroups == 6) {
|
||||
for (v = 0; v < alphaSize; v++) {
|
||||
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
|
||||
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
|
||||
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
|
||||
}
|
||||
}
|
||||
|
||||
nSelectors = 0;
|
||||
totc = 0;
|
||||
gs = 0;
|
||||
while (True) {
|
||||
|
||||
/*--- Set group start & end marks. --*/
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
|
||||
/*--
|
||||
Calculate the cost of this group as coded
|
||||
by each of the coding tables.
|
||||
--*/
|
||||
for (t = 0; t < nGroups; t++) cost[t] = 0;
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
register UInt32 cost01, cost23, cost45;
|
||||
register UInt16 icv;
|
||||
cost01 = cost23 = cost45 = 0;
|
||||
|
||||
# define BZ_ITER(nn) \
|
||||
icv = mtfv[gs+(nn)]; \
|
||||
cost01 += s->len_pack[icv][0]; \
|
||||
cost23 += s->len_pack[icv][1]; \
|
||||
cost45 += s->len_pack[icv][2]; \
|
||||
|
||||
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
|
||||
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
|
||||
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
|
||||
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
|
||||
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
|
||||
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
|
||||
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
|
||||
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
|
||||
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
|
||||
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
|
||||
|
||||
# undef BZ_ITER
|
||||
|
||||
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
|
||||
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
|
||||
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
UInt16 icv = mtfv[i];
|
||||
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
|
||||
}
|
||||
}
|
||||
|
||||
/*--
|
||||
Find the coding table which is best for this group,
|
||||
and record its identity in the selector table.
|
||||
--*/
|
||||
bc = 999999999; bt = -1;
|
||||
for (t = 0; t < nGroups; t++)
|
||||
if (cost[t] < bc) { bc = cost[t]; bt = t; };
|
||||
totc += bc;
|
||||
fave[bt]++;
|
||||
s->selector[nSelectors] = bt;
|
||||
nSelectors++;
|
||||
|
||||
/*--
|
||||
Increment the symbol frequencies for the selected table.
|
||||
--*/
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
|
||||
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
|
||||
|
||||
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
|
||||
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
|
||||
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
|
||||
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
|
||||
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
|
||||
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
|
||||
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
|
||||
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
|
||||
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
|
||||
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
|
||||
|
||||
# undef BZ_ITUR
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++)
|
||||
s->rfreq[bt][ mtfv[i] ]++;
|
||||
}
|
||||
|
||||
gs = ge+1;
|
||||
}
|
||||
if (s->verbosity >= 3) {
|
||||
VPrintf2 ( " pass %d: size is %d, grp uses are ",
|
||||
iter+1, totc/8 );
|
||||
for (t = 0; t < nGroups; t++)
|
||||
VPrintf1 ( "%d ", fave[t] );
|
||||
VPrintf0 ( "\n" );
|
||||
}
|
||||
|
||||
/*--
|
||||
Recompute the tables based on the accumulated frequencies.
|
||||
--*/
|
||||
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
|
||||
comment in huffman.c for details. */
|
||||
for (t = 0; t < nGroups; t++)
|
||||
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
|
||||
alphaSize, 17 /*20*/ );
|
||||
}
|
||||
|
||||
|
||||
AssertH( nGroups < 8, 3002 );
|
||||
AssertH( nSelectors < 32768 &&
|
||||
nSelectors <= (2 + (900000 / BZ_G_SIZE)),
|
||||
3003 );
|
||||
|
||||
|
||||
/*--- Compute MTF values for the selectors. ---*/
|
||||
{
|
||||
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
|
||||
for (i = 0; i < nGroups; i++) pos[i] = i;
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
ll_i = s->selector[i];
|
||||
j = 0;
|
||||
tmp = pos[j];
|
||||
while ( ll_i != tmp ) {
|
||||
j++;
|
||||
tmp2 = tmp;
|
||||
tmp = pos[j];
|
||||
pos[j] = tmp2;
|
||||
};
|
||||
pos[0] = tmp;
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
};
|
||||
|
||||
/*--- Assign actual codes for the tables. --*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
minLen = 32;
|
||||
maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
|
||||
AssertH ( !(minLen < 1), 3005 );
|
||||
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize );
|
||||
}
|
||||
|
||||
/*--- Transmit the mapping table. ---*/
|
||||
{
|
||||
Bool inUse16[16];
|
||||
for (i = 0; i < 16; i++) {
|
||||
inUse16[i] = False;
|
||||
for (j = 0; j < 16; j++)
|
||||
if (s->inUse[i * 16 + j]) inUse16[i] = True;
|
||||
}
|
||||
|
||||
nBytes = s->numZ;
|
||||
for (i = 0; i < 16; i++)
|
||||
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (inUse16[i])
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
|
||||
}
|
||||
|
||||
/*--- Now the selectors. ---*/
|
||||
nBytes = s->numZ;
|
||||
bsW ( s, 3, nGroups );
|
||||
bsW ( s, 15, nSelectors );
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
|
||||
bsW(s,1,0);
|
||||
}
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "selectors %d, ", s->numZ-nBytes );
|
||||
|
||||
/*--- Now the coding tables. ---*/
|
||||
nBytes = s->numZ;
|
||||
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
Int32 curr = s->len[t][0];
|
||||
bsW ( s, 5, curr );
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
|
||||
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
|
||||
bsW ( s, 1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
|
||||
|
||||
/*--- And finally, the block data proper ---*/
|
||||
nBytes = s->numZ;
|
||||
selCtr = 0;
|
||||
gs = 0;
|
||||
while (True) {
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
AssertH ( s->selector[selCtr] < nGroups, 3006 );
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
UInt16 mtfv_i;
|
||||
UChar* s_len_sel_selCtr
|
||||
= &(s->len[s->selector[selCtr]][0]);
|
||||
Int32* s_code_sel_selCtr
|
||||
= &(s->code[s->selector[selCtr]][0]);
|
||||
|
||||
# define BZ_ITAH(nn) \
|
||||
mtfv_i = mtfv[gs+(nn)]; \
|
||||
bsW ( s, \
|
||||
s_len_sel_selCtr[mtfv_i], \
|
||||
s_code_sel_selCtr[mtfv_i] )
|
||||
|
||||
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
|
||||
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
|
||||
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
|
||||
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
|
||||
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
|
||||
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
|
||||
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
|
||||
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
|
||||
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
|
||||
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
|
||||
|
||||
# undef BZ_ITAH
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
bsW ( s,
|
||||
s->len [s->selector[selCtr]] [mtfv[i]],
|
||||
s->code [s->selector[selCtr]] [mtfv[i]] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gs = ge+1;
|
||||
selCtr++;
|
||||
}
|
||||
AssertH( selCtr == nSelectors, 3007 );
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "codes %d\n", s->numZ-nBytes );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_compressBlock ( EState* s, Bool is_last_block )
|
||||
{
|
||||
if (s->nblock > 0) {
|
||||
|
||||
BZ_FINALISE_CRC ( s->blockCRC );
|
||||
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
|
||||
s->combinedCRC ^= s->blockCRC;
|
||||
if (s->blockNo > 1) s->numZ = 0;
|
||||
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf4( " block %d: crc = 0x%08x, "
|
||||
"combined CRC = 0x%08x, size = %d\n",
|
||||
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
|
||||
|
||||
BZ2_blockSort ( s );
|
||||
}
|
||||
|
||||
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
|
||||
|
||||
/*-- If this is the first block, create the stream header. --*/
|
||||
if (s->blockNo == 1) {
|
||||
BZ2_bsInitWrite ( s );
|
||||
bsPutUChar ( s, BZ_HDR_B );
|
||||
bsPutUChar ( s, BZ_HDR_Z );
|
||||
bsPutUChar ( s, BZ_HDR_h );
|
||||
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
|
||||
}
|
||||
|
||||
if (s->nblock > 0) {
|
||||
|
||||
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
|
||||
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
|
||||
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
|
||||
|
||||
/*-- Now the block's CRC, so it is in a known place. --*/
|
||||
bsPutUInt32 ( s, s->blockCRC );
|
||||
|
||||
/*--
|
||||
Now a single bit indicating (non-)randomisation.
|
||||
As of version 0.9.5, we use a better sorting algorithm
|
||||
which makes randomisation unnecessary. So always set
|
||||
the randomised bit to 'no'. Of course, the decoder
|
||||
still needs to be able to handle randomised blocks
|
||||
so as to maintain backwards compatibility with
|
||||
older versions of bzip2.
|
||||
--*/
|
||||
bsW(s,1,0);
|
||||
|
||||
bsW ( s, 24, s->origPtr );
|
||||
generateMTFValues ( s );
|
||||
sendMTFValues ( s );
|
||||
}
|
||||
|
||||
|
||||
/*-- If this is the last block, add the stream trailer. --*/
|
||||
if (is_last_block) {
|
||||
|
||||
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
|
||||
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
|
||||
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
|
||||
bsPutUInt32 ( s, s->combinedCRC );
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
|
||||
bsFinishWrite ( s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
@@ -1,104 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for doing CRCs ---*/
|
||||
/*--- crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*--
|
||||
I think this is an implementation of the AUTODIN-II,
|
||||
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
|
||||
from code by Rob Warnock, in Section 51 of the
|
||||
comp.compression FAQ.
|
||||
--*/
|
||||
|
||||
UInt32 BZ2_crc32Table[256] = {
|
||||
|
||||
/*-- Ugly, innit? --*/
|
||||
|
||||
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
|
||||
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
|
||||
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
|
||||
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
|
||||
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
|
||||
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
|
||||
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
|
||||
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
|
||||
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
|
||||
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
|
||||
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
|
||||
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
|
||||
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
|
||||
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
|
||||
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
|
||||
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
|
||||
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
|
||||
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
|
||||
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
|
||||
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
|
||||
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
|
||||
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
|
||||
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
|
||||
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
|
||||
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
|
||||
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
|
||||
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
|
||||
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
|
||||
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
|
||||
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
|
||||
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
|
||||
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
|
||||
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
|
||||
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
|
||||
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
|
||||
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
|
||||
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
|
||||
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
|
||||
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
|
||||
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
|
||||
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
|
||||
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
|
||||
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
|
||||
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
|
||||
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
|
||||
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
|
||||
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
|
||||
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
|
||||
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
|
||||
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
|
||||
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
|
||||
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
|
||||
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
|
||||
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
|
||||
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
|
||||
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
|
||||
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
|
||||
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
|
||||
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
|
||||
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
|
||||
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
|
||||
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
|
||||
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
|
||||
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
@@ -1,646 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Decompression machinery ---*/
|
||||
/*--- decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_d ( DState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->seqToUnseq[s->nInUse] = i;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define RETURN(rrr) \
|
||||
{ retVal = rrr; goto save_state_and_return; };
|
||||
|
||||
#define GET_BITS(lll,vvv,nnn) \
|
||||
case lll: s->state = lll; \
|
||||
while (True) { \
|
||||
if (s->bsLive >= nnn) { \
|
||||
UInt32 v; \
|
||||
v = (s->bsBuff >> \
|
||||
(s->bsLive-nnn)) & ((1 << nnn)-1); \
|
||||
s->bsLive -= nnn; \
|
||||
vvv = v; \
|
||||
break; \
|
||||
} \
|
||||
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
|
||||
s->bsBuff \
|
||||
= (s->bsBuff << 8) | \
|
||||
((UInt32) \
|
||||
(*((UChar*)(s->strm->next_in)))); \
|
||||
s->bsLive += 8; \
|
||||
s->strm->next_in++; \
|
||||
s->strm->avail_in--; \
|
||||
s->strm->total_in_lo32++; \
|
||||
if (s->strm->total_in_lo32 == 0) \
|
||||
s->strm->total_in_hi32++; \
|
||||
}
|
||||
|
||||
#define GET_UCHAR(lll,uuu) \
|
||||
GET_BITS(lll,uuu,8)
|
||||
|
||||
#define GET_BIT(lll,uuu) \
|
||||
GET_BITS(lll,uuu,1)
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define GET_MTF_VAL(label1,label2,lval) \
|
||||
{ \
|
||||
if (groupPos == 0) { \
|
||||
groupNo++; \
|
||||
if (groupNo >= nSelectors) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
groupPos = BZ_G_SIZE; \
|
||||
gSel = s->selector[groupNo]; \
|
||||
gMinlen = s->minLens[gSel]; \
|
||||
gLimit = &(s->limit[gSel][0]); \
|
||||
gPerm = &(s->perm[gSel][0]); \
|
||||
gBase = &(s->base[gSel][0]); \
|
||||
} \
|
||||
groupPos--; \
|
||||
zn = gMinlen; \
|
||||
GET_BITS(label1, zvec, zn); \
|
||||
while (1) { \
|
||||
if (zn > 20 /* the longest code */) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
if (zvec <= gLimit[zn]) break; \
|
||||
zn++; \
|
||||
GET_BIT(label2, zj); \
|
||||
zvec = (zvec << 1) | zj; \
|
||||
}; \
|
||||
if (zvec - gBase[zn] < 0 \
|
||||
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
lval = gPerm[zvec - gBase[zn]]; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
Int32 BZ2_decompress ( DState* s )
|
||||
{
|
||||
UChar uc;
|
||||
Int32 retVal;
|
||||
Int32 minLen, maxLen;
|
||||
bz_stream* strm = s->strm;
|
||||
|
||||
/* stuff that needs to be saved/restored */
|
||||
Int32 i;
|
||||
Int32 j;
|
||||
Int32 t;
|
||||
Int32 alphaSize;
|
||||
Int32 nGroups;
|
||||
Int32 nSelectors;
|
||||
Int32 EOB;
|
||||
Int32 groupNo;
|
||||
Int32 groupPos;
|
||||
Int32 nextSym;
|
||||
Int32 nblockMAX;
|
||||
Int32 nblock;
|
||||
Int32 es;
|
||||
Int32 N;
|
||||
Int32 curr;
|
||||
Int32 zt;
|
||||
Int32 zn;
|
||||
Int32 zvec;
|
||||
Int32 zj;
|
||||
Int32 gSel;
|
||||
Int32 gMinlen;
|
||||
Int32* gLimit;
|
||||
Int32* gBase;
|
||||
Int32* gPerm;
|
||||
|
||||
if (s->state == BZ_X_MAGIC_1) {
|
||||
/*initialise the save area*/
|
||||
s->save_i = 0;
|
||||
s->save_j = 0;
|
||||
s->save_t = 0;
|
||||
s->save_alphaSize = 0;
|
||||
s->save_nGroups = 0;
|
||||
s->save_nSelectors = 0;
|
||||
s->save_EOB = 0;
|
||||
s->save_groupNo = 0;
|
||||
s->save_groupPos = 0;
|
||||
s->save_nextSym = 0;
|
||||
s->save_nblockMAX = 0;
|
||||
s->save_nblock = 0;
|
||||
s->save_es = 0;
|
||||
s->save_N = 0;
|
||||
s->save_curr = 0;
|
||||
s->save_zt = 0;
|
||||
s->save_zn = 0;
|
||||
s->save_zvec = 0;
|
||||
s->save_zj = 0;
|
||||
s->save_gSel = 0;
|
||||
s->save_gMinlen = 0;
|
||||
s->save_gLimit = NULL;
|
||||
s->save_gBase = NULL;
|
||||
s->save_gPerm = NULL;
|
||||
}
|
||||
|
||||
/*restore from the save area*/
|
||||
i = s->save_i;
|
||||
j = s->save_j;
|
||||
t = s->save_t;
|
||||
alphaSize = s->save_alphaSize;
|
||||
nGroups = s->save_nGroups;
|
||||
nSelectors = s->save_nSelectors;
|
||||
EOB = s->save_EOB;
|
||||
groupNo = s->save_groupNo;
|
||||
groupPos = s->save_groupPos;
|
||||
nextSym = s->save_nextSym;
|
||||
nblockMAX = s->save_nblockMAX;
|
||||
nblock = s->save_nblock;
|
||||
es = s->save_es;
|
||||
N = s->save_N;
|
||||
curr = s->save_curr;
|
||||
zt = s->save_zt;
|
||||
zn = s->save_zn;
|
||||
zvec = s->save_zvec;
|
||||
zj = s->save_zj;
|
||||
gSel = s->save_gSel;
|
||||
gMinlen = s->save_gMinlen;
|
||||
gLimit = s->save_gLimit;
|
||||
gBase = s->save_gBase;
|
||||
gPerm = s->save_gPerm;
|
||||
|
||||
retVal = BZ_OK;
|
||||
|
||||
switch (s->state) {
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_1, uc);
|
||||
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_2, uc);
|
||||
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_3, uc)
|
||||
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
|
||||
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
|
||||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
s->blockSize100k -= BZ_HDR_0;
|
||||
|
||||
if (s->smallDecompress) {
|
||||
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
|
||||
s->ll4 = BZALLOC(
|
||||
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
|
||||
);
|
||||
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
|
||||
} else {
|
||||
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
|
||||
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
|
||||
}
|
||||
|
||||
GET_UCHAR(BZ_X_BLKHDR_1, uc);
|
||||
|
||||
if (uc == 0x17) goto endhdr_2;
|
||||
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_2, uc);
|
||||
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_3, uc);
|
||||
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_4, uc);
|
||||
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_5, uc);
|
||||
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_6, uc);
|
||||
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->currBlockNo++;
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
|
||||
|
||||
s->storedBlockCRC = 0;
|
||||
GET_UCHAR(BZ_X_BCRC_1, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_2, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_3, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_4, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
|
||||
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
|
||||
|
||||
s->origPtr = 0;
|
||||
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
|
||||
if (s->origPtr < 0)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
if (s->origPtr > 10 + 100000*s->blockSize100k)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*--- Receive the mapping table ---*/
|
||||
for (i = 0; i < 16; i++) {
|
||||
GET_BIT(BZ_X_MAPPING_1, uc);
|
||||
if (uc == 1)
|
||||
s->inUse16[i] = True; else
|
||||
s->inUse16[i] = False;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) s->inUse[i] = False;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (s->inUse16[i])
|
||||
for (j = 0; j < 16; j++) {
|
||||
GET_BIT(BZ_X_MAPPING_2, uc);
|
||||
if (uc == 1) s->inUse[i * 16 + j] = True;
|
||||
}
|
||||
makeMaps_d ( s );
|
||||
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
|
||||
alphaSize = s->nInUse+2;
|
||||
|
||||
/*--- Now the selectors ---*/
|
||||
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
|
||||
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
|
||||
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
|
||||
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
j = 0;
|
||||
while (True) {
|
||||
GET_BIT(BZ_X_SELECTOR_3, uc);
|
||||
if (uc == 0) break;
|
||||
j++;
|
||||
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
|
||||
/*--- Undo the MTF values for the selectors. ---*/
|
||||
{
|
||||
UChar pos[BZ_N_GROUPS], tmp, v;
|
||||
for (v = 0; v < nGroups; v++) pos[v] = v;
|
||||
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
v = s->selectorMtf[i];
|
||||
tmp = pos[v];
|
||||
while (v > 0) { pos[v] = pos[v-1]; v--; }
|
||||
pos[0] = tmp;
|
||||
s->selector[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Now the coding tables ---*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
GET_BITS(BZ_X_CODING_1, curr, 5);
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (True) {
|
||||
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
|
||||
GET_BIT(BZ_X_CODING_2, uc);
|
||||
if (uc == 0) break;
|
||||
GET_BIT(BZ_X_CODING_3, uc);
|
||||
if (uc == 0) curr++; else curr--;
|
||||
}
|
||||
s->len[t][i] = curr;
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Create the Huffman decoding tables ---*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
minLen = 32;
|
||||
maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
BZ2_hbCreateDecodeTables (
|
||||
&(s->limit[t][0]),
|
||||
&(s->base[t][0]),
|
||||
&(s->perm[t][0]),
|
||||
&(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize
|
||||
);
|
||||
s->minLens[t] = minLen;
|
||||
}
|
||||
|
||||
/*--- Now the MTF values ---*/
|
||||
|
||||
EOB = s->nInUse+1;
|
||||
nblockMAX = 100000 * s->blockSize100k;
|
||||
groupNo = -1;
|
||||
groupPos = 0;
|
||||
|
||||
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
|
||||
|
||||
/*-- MTF init --*/
|
||||
{
|
||||
Int32 ii, jj, kk;
|
||||
kk = MTFA_SIZE-1;
|
||||
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
|
||||
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
|
||||
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
|
||||
kk--;
|
||||
}
|
||||
s->mtfbase[ii] = kk + 1;
|
||||
}
|
||||
}
|
||||
/*-- end MTF init --*/
|
||||
|
||||
nblock = 0;
|
||||
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
|
||||
|
||||
while (True) {
|
||||
|
||||
if (nextSym == EOB) break;
|
||||
|
||||
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
|
||||
|
||||
es = -1;
|
||||
N = 1;
|
||||
do {
|
||||
/* Check that N doesn't get too big, so that es doesn't
|
||||
go negative. The maximum value that can be
|
||||
RUNA/RUNB encoded is equal to the block size (post
|
||||
the initial RLE), viz, 900k, so bounding N at 2
|
||||
million should guard against overflow without
|
||||
rejecting any legitimate inputs. */
|
||||
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
|
||||
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
|
||||
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
|
||||
N = N * 2;
|
||||
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
|
||||
}
|
||||
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
|
||||
|
||||
es++;
|
||||
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
|
||||
s->unzftab[uc] += es;
|
||||
|
||||
if (s->smallDecompress)
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->ll16[nblock] = (UInt16)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
}
|
||||
else
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->tt[nblock] = (UInt32)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
};
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- uc = MTF ( nextSym-1 ) --*/
|
||||
{
|
||||
Int32 ii, jj, kk, pp, lno, off;
|
||||
UInt32 nn;
|
||||
nn = (UInt32)(nextSym - 1);
|
||||
|
||||
if (nn < MTFL_SIZE) {
|
||||
/* avoid general-case expense */
|
||||
pp = s->mtfbase[0];
|
||||
uc = s->mtfa[pp+nn];
|
||||
while (nn > 3) {
|
||||
Int32 z = pp+nn;
|
||||
s->mtfa[(z) ] = s->mtfa[(z)-1];
|
||||
s->mtfa[(z)-1] = s->mtfa[(z)-2];
|
||||
s->mtfa[(z)-2] = s->mtfa[(z)-3];
|
||||
s->mtfa[(z)-3] = s->mtfa[(z)-4];
|
||||
nn -= 4;
|
||||
}
|
||||
while (nn > 0) {
|
||||
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
|
||||
};
|
||||
s->mtfa[pp] = uc;
|
||||
} else {
|
||||
/* general case */
|
||||
lno = nn / MTFL_SIZE;
|
||||
off = nn % MTFL_SIZE;
|
||||
pp = s->mtfbase[lno] + off;
|
||||
uc = s->mtfa[pp];
|
||||
while (pp > s->mtfbase[lno]) {
|
||||
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
|
||||
};
|
||||
s->mtfbase[lno]++;
|
||||
while (lno > 0) {
|
||||
s->mtfbase[lno]--;
|
||||
s->mtfa[s->mtfbase[lno]]
|
||||
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
|
||||
lno--;
|
||||
}
|
||||
s->mtfbase[0]--;
|
||||
s->mtfa[s->mtfbase[0]] = uc;
|
||||
if (s->mtfbase[0] == 0) {
|
||||
kk = MTFA_SIZE-1;
|
||||
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
|
||||
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
|
||||
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
|
||||
kk--;
|
||||
}
|
||||
s->mtfbase[ii] = kk + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-- end uc = MTF ( nextSym-1 ) --*/
|
||||
|
||||
s->unzftab[s->seqToUnseq[uc]]++;
|
||||
if (s->smallDecompress)
|
||||
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
|
||||
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
|
||||
nblock++;
|
||||
|
||||
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we know what nblock is, we can do a better sanity
|
||||
check on s->origPtr.
|
||||
*/
|
||||
if (s->origPtr < 0 || s->origPtr >= nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- Set up cftab to facilitate generation of T^(-1) --*/
|
||||
/* Check: unzftab entries in range. */
|
||||
for (i = 0; i <= 255; i++) {
|
||||
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
/* Actually generate cftab. */
|
||||
s->cftab[0] = 0;
|
||||
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
|
||||
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
|
||||
/* Check: cftab entries in range. */
|
||||
for (i = 0; i <= 256; i++) {
|
||||
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
|
||||
/* s->cftab[i] can legitimately be == nblock */
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
/* Check: cftab entries non-descending. */
|
||||
for (i = 1; i <= 256; i++) {
|
||||
if (s->cftab[i-1] > s->cftab[i]) {
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
s->state_out_len = 0;
|
||||
s->state_out_ch = 0;
|
||||
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
|
||||
s->state = BZ_X_OUTPUT;
|
||||
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
|
||||
|
||||
if (s->smallDecompress) {
|
||||
|
||||
/*-- Make a copy of cftab, used in generation of T --*/
|
||||
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
|
||||
|
||||
/*-- compute the T vector --*/
|
||||
for (i = 0; i < nblock; i++) {
|
||||
uc = (UChar)(s->ll16[i]);
|
||||
SET_LL(i, s->cftabCopy[uc]);
|
||||
s->cftabCopy[uc]++;
|
||||
}
|
||||
|
||||
/*-- Compute T^(-1) by pointer reversal on T --*/
|
||||
i = s->origPtr;
|
||||
j = GET_LL(i);
|
||||
do {
|
||||
Int32 tmp = GET_LL(j);
|
||||
SET_LL(j, i);
|
||||
i = j;
|
||||
j = tmp;
|
||||
}
|
||||
while (i != s->origPtr);
|
||||
|
||||
s->tPos = s->origPtr;
|
||||
s->nblock_used = 0;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*-- compute the T^(-1) vector --*/
|
||||
for (i = 0; i < nblock; i++) {
|
||||
uc = (UChar)(s->tt[i] & 0xff);
|
||||
s->tt[s->cftab[uc]] |= (i << 8);
|
||||
s->cftab[uc]++;
|
||||
}
|
||||
|
||||
s->tPos = s->tt[s->origPtr] >> 8;
|
||||
s->nblock_used = 0;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RETURN(BZ_OK);
|
||||
|
||||
|
||||
|
||||
endhdr_2:
|
||||
|
||||
GET_UCHAR(BZ_X_ENDHDR_2, uc);
|
||||
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_3, uc);
|
||||
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_4, uc);
|
||||
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_5, uc);
|
||||
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_6, uc);
|
||||
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->storedCombinedCRC = 0;
|
||||
GET_UCHAR(BZ_X_CCRC_1, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_2, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_3, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_4, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
|
||||
s->state = BZ_X_IDLE;
|
||||
RETURN(BZ_STREAM_END);
|
||||
|
||||
default: AssertH ( False, 4001 );
|
||||
}
|
||||
|
||||
AssertH ( False, 4002 );
|
||||
|
||||
save_state_and_return:
|
||||
|
||||
s->save_i = i;
|
||||
s->save_j = j;
|
||||
s->save_t = t;
|
||||
s->save_alphaSize = alphaSize;
|
||||
s->save_nGroups = nGroups;
|
||||
s->save_nSelectors = nSelectors;
|
||||
s->save_EOB = EOB;
|
||||
s->save_groupNo = groupNo;
|
||||
s->save_groupPos = groupPos;
|
||||
s->save_nextSym = nextSym;
|
||||
s->save_nblockMAX = nblockMAX;
|
||||
s->save_nblock = nblock;
|
||||
s->save_es = es;
|
||||
s->save_N = N;
|
||||
s->save_curr = curr;
|
||||
s->save_zt = zt;
|
||||
s->save_zn = zn;
|
||||
s->save_zvec = zvec;
|
||||
s->save_zj = zj;
|
||||
s->save_gSel = gSel;
|
||||
s->save_gMinlen = gMinlen;
|
||||
s->save_gLimit = gLimit;
|
||||
s->save_gBase = gBase;
|
||||
s->save_gPerm = gPerm;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
137
android/jni/hpatch.c
Normal file
137
android/jni/hpatch.c
Normal file
@@ -0,0 +1,137 @@
|
||||
// hpatch.c
|
||||
// Copyright 2021 housisong, All rights reserved
|
||||
#include "hpatch.h"
|
||||
#include "HDiffPatch/libHDiffPatch/HPatch/patch.h"
|
||||
#include "HDiffPatch/file_for_patch.h"
|
||||
|
||||
//#define _CompressPlugin_zlib
|
||||
//#define _CompressPlugin_bz2
|
||||
#define _CompressPlugin_lzma
|
||||
#define _CompressPlugin_lzma2
|
||||
#define _IsNeedIncludeDefaultCompressHead 0
|
||||
#include "lzma/C/LzmaDec.h"
|
||||
#include "lzma/C/Lzma2Dec.h"
|
||||
#include "HDiffPatch/decompress_plugin_demo.h"
|
||||
|
||||
#define kMaxLoadMemOldSize ((1<<20)*8)
|
||||
|
||||
#define _check(v,errorType) do{ \
|
||||
if (!(v)){ if (result==kHPatch_ok) result=errorType; if (!_isInClear){ goto _clear; }; } }while(0)
|
||||
|
||||
int hpatch_getInfo_by_mem(hpatch_singleCompressedDiffInfo* out_patinfo,
|
||||
const uint8_t* pat,size_t patsize){
|
||||
hpatch_TStreamInput patStream;
|
||||
mem_as_hStreamInput(&patStream,pat,pat+patsize);
|
||||
if (!getSingleCompressedDiffInfo(out_patinfo,&patStream,0))
|
||||
return kHPatch_error_info;//data error;
|
||||
return kHPatch_ok; //ok
|
||||
}
|
||||
|
||||
static hpatch_TDecompress* getDecompressPlugin(const char* compressType){
|
||||
#ifdef _CompressPlugin_zlib
|
||||
if (zlibDecompressPlugin.is_can_open(compressType))
|
||||
return &zlibDecompressPlugin;
|
||||
#endif
|
||||
#ifdef _CompressPlugin_bz2
|
||||
if (bz2DecompressPlugin.is_can_open(compressType))
|
||||
return &bz2DecompressPlugin;
|
||||
#endif
|
||||
#ifdef _CompressPlugin_lzma
|
||||
if (lzmaDecompressPlugin.is_can_open(compressType))
|
||||
return &lzmaDecompressPlugin;
|
||||
#endif
|
||||
#ifdef _CompressPlugin_lzma2
|
||||
if (lzma2DecompressPlugin.is_can_open(compressType))
|
||||
return &lzma2DecompressPlugin;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static int hpatch_by_stream(const hpatch_TStreamInput* old,hpatch_BOOL isLoadOldAllToMem,const hpatch_TStreamInput* pat,
|
||||
hpatch_TStreamOutput* out_new,const hpatch_singleCompressedDiffInfo* patInfo){
|
||||
int result=kHPatch_ok;
|
||||
int _isInClear=hpatch_FALSE;
|
||||
hpatch_TDecompress* decompressPlugin=0;
|
||||
uint8_t* temp_cache=0;
|
||||
size_t temp_cache_size;
|
||||
hpatch_singleCompressedDiffInfo _patinfo;
|
||||
hpatch_TStreamInput _old;
|
||||
{// info
|
||||
if (!patInfo){
|
||||
_check(getSingleCompressedDiffInfo(&_patinfo,pat,0),kHPatch_error_info);
|
||||
patInfo=&_patinfo;
|
||||
}
|
||||
_check(old->streamSize==patInfo->oldDataSize,kHPatch_error_old_size);
|
||||
_check(out_new->streamSize>=patInfo->newDataSize,kHPatch_error_new_size);
|
||||
out_new->streamSize=patInfo->newDataSize;
|
||||
if (strlen(patInfo->compressType)>0){
|
||||
decompressPlugin=getDecompressPlugin(patInfo->compressType);
|
||||
_check(decompressPlugin,kHPatch_error_compressType);
|
||||
}
|
||||
}
|
||||
{// mem
|
||||
size_t mem_size;
|
||||
size_t oldSize=(size_t)old->streamSize;
|
||||
isLoadOldAllToMem=isLoadOldAllToMem&&(old->streamSize<=kMaxLoadMemOldSize);
|
||||
temp_cache_size=patInfo->stepMemSize+hpatch_kFileIOBufBetterSize*3;
|
||||
mem_size=temp_cache_size+(isLoadOldAllToMem?oldSize:0);
|
||||
temp_cache=malloc(mem_size);
|
||||
_check(temp_cache,kHPatch_error_malloc);
|
||||
if (isLoadOldAllToMem){//load old to mem
|
||||
uint8_t* oldMem=temp_cache+temp_cache_size;
|
||||
_check(old->read(old,0,oldMem,oldMem+oldSize),kHPatch_error_old_fread);
|
||||
mem_as_hStreamInput(&_old,oldMem,oldMem+oldSize);
|
||||
old=&_old;
|
||||
}
|
||||
}
|
||||
|
||||
_check(patch_single_compressed_diff(out_new,old,pat,patInfo->diffDataPos,
|
||||
patInfo->uncompressedSize,decompressPlugin,patInfo->coverCount,
|
||||
patInfo->stepMemSize,temp_cache,temp_cache+temp_cache_size),kHPatch_error_patch);
|
||||
|
||||
_clear:
|
||||
_isInClear=hpatch_TRUE;
|
||||
if (temp_cache){ free(temp_cache); temp_cache=0; }
|
||||
return result;
|
||||
}
|
||||
|
||||
int hpatch_by_mem(const uint8_t* old,size_t oldsize,uint8_t* newBuf,size_t newsize,
|
||||
const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo){
|
||||
hpatch_TStreamInput oldStream;
|
||||
hpatch_TStreamInput patStream;
|
||||
hpatch_TStreamOutput newStream;
|
||||
mem_as_hStreamInput(&oldStream,old,old+oldsize);
|
||||
mem_as_hStreamInput(&patStream,pat,pat+patsize);
|
||||
mem_as_hStreamOutput(&newStream,newBuf,newBuf+newsize);
|
||||
return hpatch_by_stream(&oldStream,hpatch_FALSE,&patStream,&newStream,patInfo);
|
||||
}
|
||||
|
||||
int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfile){
|
||||
int result=kHPatch_ok;
|
||||
int _isInClear=hpatch_FALSE;
|
||||
int patch_result;
|
||||
hpatch_TFileStreamInput oldStream;
|
||||
hpatch_TFileStreamInput patStream;
|
||||
hpatch_TFileStreamOutput newStream;
|
||||
hpatch_TFileStreamInput_init(&oldStream);
|
||||
hpatch_TFileStreamInput_init(&patStream);
|
||||
hpatch_TFileStreamOutput_init(&newStream);
|
||||
|
||||
_check(hpatch_TFileStreamInput_open(&oldStream,oldfile),kHPatch_error_old_fopen);
|
||||
_check(hpatch_TFileStreamInput_open(&patStream,patchfile),kHPatch_error_pat_fopen);
|
||||
_check(hpatch_TFileStreamOutput_open(&newStream,newfile,~(hpatch_StreamPos_t)0),kHPatch_error_new_fopen);
|
||||
|
||||
patch_result=hpatch_by_stream(&oldStream.base,hpatch_TRUE,&patStream.base,&newStream.base,0);
|
||||
if (patch_result!=kHPatch_ok){
|
||||
_check(!oldStream.fileError,kHPatch_error_old_fread);
|
||||
_check(!patStream.fileError,kHPatch_error_pat_fread);
|
||||
_check(!newStream.fileError,kHPatch_error_new_fwrite);
|
||||
_check(hpatch_FALSE,patch_result);
|
||||
}
|
||||
|
||||
_clear:
|
||||
_isInClear=hpatch_TRUE;
|
||||
_check(hpatch_TFileStreamInput_close(&oldStream),kHPatch_error_old_fclose);
|
||||
_check(hpatch_TFileStreamInput_close(&patStream),kHPatch_error_pat_fclose);
|
||||
_check(hpatch_TFileStreamOutput_close(&newStream),kHPatch_error_new_fclose);
|
||||
return result;
|
||||
}
|
44
android/jni/hpatch.h
Normal file
44
android/jni/hpatch.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// hpatch.h
|
||||
// import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
|
||||
// Copyright 2021 housisong, All rights reserved
|
||||
|
||||
#ifndef HDIFFPATCH_PATCH_H
|
||||
#define HDIFFPATCH_PATCH_H
|
||||
# include <stdint.h> //for uint8_t
|
||||
#include "HDiffPatch/libHDiffPatch/HPatch/patch_types.h" //for hpatch_singleCompressedDiffInfo
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//result
|
||||
enum {
|
||||
kHPatch_ok = 0,
|
||||
kHPatch_error_malloc =-1,
|
||||
kHPatch_error_info =-2,
|
||||
kHPatch_error_compressType =-3,
|
||||
kHPatch_error_patch =-4,
|
||||
kHPatch_error_old_fopen =-5,
|
||||
kHPatch_error_old_fread =-6,
|
||||
kHPatch_error_old_fclose =-7,
|
||||
kHPatch_error_pat_fopen =-8,
|
||||
kHPatch_error_pat_fread =-9,
|
||||
kHPatch_error_pat_fclose =-10,
|
||||
kHPatch_error_new_fopen =-11,
|
||||
kHPatch_error_new_fwrite =-12,
|
||||
kHPatch_error_new_fclose =-13,
|
||||
kHPatch_error_old_size =-14,
|
||||
kHPatch_error_new_size =-15,
|
||||
};
|
||||
|
||||
int hpatch_getInfo_by_mem(hpatch_singleCompressedDiffInfo* out_patinfo,
|
||||
const uint8_t* pat,size_t patsize);
|
||||
|
||||
//patInfo can NULL
|
||||
int hpatch_by_mem(const uint8_t* old,size_t oldsize, uint8_t* newBuf,size_t newsize,
|
||||
const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo);
|
||||
int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfile);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //HDIFFPATCH_PATCH_H
|
@@ -1,205 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Huffman coding low-level stuff ---*/
|
||||
/*--- huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
|
||||
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
|
||||
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
|
||||
|
||||
#define ADDWEIGHTS(zw1,zw2) \
|
||||
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
|
||||
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
|
||||
|
||||
#define UPHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (weight[tmp] < weight[heap[zz >> 1]]) { \
|
||||
heap[zz] = heap[zz >> 1]; \
|
||||
zz >>= 1; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
#define DOWNHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, yy, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (True) { \
|
||||
yy = zz << 1; \
|
||||
if (yy > nHeap) break; \
|
||||
if (yy < nHeap && \
|
||||
weight[heap[yy+1]] < weight[heap[yy]]) \
|
||||
yy++; \
|
||||
if (weight[tmp] < weight[heap[yy]]) break; \
|
||||
heap[zz] = heap[yy]; \
|
||||
zz = yy; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
{
|
||||
/*--
|
||||
Nodes and heap entries run from 1. Entry 0
|
||||
for both the heap and nodes is a sentinel.
|
||||
--*/
|
||||
Int32 nNodes, nHeap, n1, n2, i, j, k;
|
||||
Bool tooLong;
|
||||
|
||||
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
|
||||
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
|
||||
|
||||
while (True) {
|
||||
|
||||
nNodes = alphaSize;
|
||||
nHeap = 0;
|
||||
|
||||
heap[0] = 0;
|
||||
weight[0] = 0;
|
||||
parent[0] = -2;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
parent[i] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = i;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
|
||||
|
||||
while (nHeap > 1) {
|
||||
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
nNodes++;
|
||||
parent[n1] = parent[n2] = nNodes;
|
||||
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
|
||||
parent[nNodes] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = nNodes;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
|
||||
|
||||
tooLong = False;
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (parent[k] >= 0) { k = parent[k]; j++; }
|
||||
len[i-1] = j;
|
||||
if (j > maxLen) tooLong = True;
|
||||
}
|
||||
|
||||
if (! tooLong) break;
|
||||
|
||||
/* 17 Oct 04: keep-going condition for the following loop used
|
||||
to be 'i < alphaSize', which missed the last element,
|
||||
theoretically leading to the possibility of the compressor
|
||||
looping. However, this count-scaling step is only needed if
|
||||
one of the generated Huffman code words is longer than
|
||||
maxLen, which up to and including version 1.0.2 was 20 bits,
|
||||
which is extremely unlikely. In version 1.0.3 maxLen was
|
||||
changed to 17 bits, which has minimal effect on compression
|
||||
ratio, but does mean this scaling step is used from time to
|
||||
time, enough to verify that it works.
|
||||
|
||||
This means that bzip2-1.0.3 and later will only produce
|
||||
Huffman codes with a maximum length of 17 bits. However, in
|
||||
order to preserve backwards compatibility with bitstreams
|
||||
produced by versions pre-1.0.3, the decompressor must still
|
||||
handle lengths of up to 20. */
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = weight[i] >> 8;
|
||||
j = 1 + (j / 2);
|
||||
weight[i] = j << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 n, vec, i;
|
||||
|
||||
vec = 0;
|
||||
for (n = minLen; n <= maxLen; n++) {
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
if (length[i] == n) { code[i] = vec; vec++; };
|
||||
vec <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 pp, i, j, vec;
|
||||
|
||||
pp = 0;
|
||||
for (i = minLen; i <= maxLen; i++)
|
||||
for (j = 0; j < alphaSize; j++)
|
||||
if (length[j] == i) { perm[pp] = j; pp++; };
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
|
||||
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
|
||||
|
||||
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
|
||||
vec = 0;
|
||||
|
||||
for (i = minLen; i <= maxLen; i++) {
|
||||
vec += (base[i+1] - base[i]);
|
||||
limit[i] = vec-1;
|
||||
vec <<= 1;
|
||||
}
|
||||
for (i = minLen + 1; i <= maxLen; i++)
|
||||
base[i] = ((limit[i-1] + 1) << 1) - base[i];
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
1
android/jni/lzma
Submodule
1
android/jni/lzma
Submodule
Submodule android/jni/lzma added at c80bb80bbb
@@ -1,84 +0,0 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for randomising repetitive blocks ---*/
|
||||
/*--- randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int32 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,7 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.reactnative.modules.update">
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<application>
|
||||
<meta-data android:name="pushy_build_time" android:value="@string/pushy_build_time" />
|
||||
<provider
|
||||
android:name=".PushyFileProvider"
|
||||
android:authorities="${applicationId}.pushy.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/pushy_file_paths" />
|
||||
</provider>
|
||||
</application>
|
||||
</manifest>
|
||||
|
@@ -15,32 +15,29 @@ import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.HashMap;
|
||||
|
||||
import okio.BufferedSink;
|
||||
import okio.BufferedSource;
|
||||
import okio.Okio;
|
||||
import static cn.reactnative.modules.update.UpdateModule.sendEvent;
|
||||
/**
|
||||
* Created by tdzl2003 on 3/31/16.
|
||||
*/
|
||||
|
||||
|
||||
class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
final int DOWNLOAD_CHUNK_SIZE = 4096;
|
||||
|
||||
Context context;
|
||||
String hash;
|
||||
|
||||
DownloadTask(Context context) {
|
||||
this.context = context;
|
||||
@@ -69,7 +66,10 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadFile(String url, File writePath) throws IOException {
|
||||
private void downloadFile(DownloadTaskParams param) throws IOException {
|
||||
String url = param.url;
|
||||
File writePath = param.targetFile;
|
||||
this.hash = param.hash;
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
Request request = new Request.Builder().url(url)
|
||||
.build();
|
||||
@@ -92,22 +92,25 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
}
|
||||
|
||||
long bytesRead = 0;
|
||||
long totalRead = 0;
|
||||
double lastProgressValue=0;
|
||||
long received = 0;
|
||||
int currentPercentage = 0;
|
||||
while ((bytesRead = source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
|
||||
totalRead += bytesRead;
|
||||
received += bytesRead;
|
||||
sink.emit();
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Progress " + totalRead + "/" + contentLength);
|
||||
Log.d("RNUpdate", "Progress " + received + "/" + contentLength);
|
||||
}
|
||||
double progress = Math.round(((double) totalRead * 100) / contentLength);
|
||||
if ((progress != lastProgressValue) || (totalRead == contentLength)) {
|
||||
lastProgressValue = progress;
|
||||
publishProgress(new long[]{(long)progress,totalRead, contentLength});
|
||||
|
||||
int percentage = (int)(received * 100.0 / contentLength + 0.5);
|
||||
if (percentage > currentPercentage) {
|
||||
currentPercentage = percentage;
|
||||
publishProgress(new long[]{received, contentLength});
|
||||
}
|
||||
}
|
||||
if (totalRead != contentLength) {
|
||||
throw new Error("Unexpected eof while reading ppk");
|
||||
if (received != contentLength) {
|
||||
throw new Error("Unexpected eof while reading downloaded update");
|
||||
}
|
||||
publishProgress(new long[]{received, contentLength});
|
||||
sink.writeAll(source);
|
||||
sink.close();
|
||||
|
||||
@@ -120,30 +123,17 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
protected void onProgressUpdate(long[]... values) {
|
||||
super.onProgressUpdate(values);
|
||||
WritableMap params = Arguments.createMap();
|
||||
params.putDouble("progress", (values[0][0]));
|
||||
params.putDouble("totalRead", (values[0][1]));
|
||||
params.putDouble("contentLength", (values[0][2]));
|
||||
sendEvent("progress", params);
|
||||
params.putDouble("received", (values[0][0]));
|
||||
params.putDouble("total", (values[0][1]));
|
||||
params.putString("hash", this.hash);
|
||||
sendEvent("RCTPushyDownloadProgress", params);
|
||||
|
||||
}
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
byte[] buffer = new byte[1024*4];
|
||||
|
||||
private static native byte[] bsdiffPatch(byte[] origin, byte[] patch);
|
||||
private static native byte[] hdiffPatch(byte[] origin, byte[] patch);
|
||||
|
||||
private void unzipToFile(ZipInputStream zis, File fmd) throws IOException {
|
||||
int count;
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(fmd);
|
||||
|
||||
while ((count = zis.read(buffer)) != -1)
|
||||
{
|
||||
fout.write(buffer, 0, count);
|
||||
}
|
||||
|
||||
fout.close();
|
||||
zis.closeEntry();
|
||||
}
|
||||
|
||||
private void copyFile(File from, File fmd) throws IOException {
|
||||
int count;
|
||||
@@ -160,7 +150,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
in.close();
|
||||
}
|
||||
|
||||
private byte[] readBytes(ZipInputStream zis) throws IOException {
|
||||
private byte[] readBytes(InputStream zis) throws IOException {
|
||||
int count;
|
||||
|
||||
ByteArrayOutputStream fout = new ByteArrayOutputStream();
|
||||
@@ -170,7 +160,7 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
}
|
||||
|
||||
fout.close();
|
||||
zis.closeEntry();
|
||||
zis.close();
|
||||
return fout.toByteArray();
|
||||
}
|
||||
|
||||
@@ -236,18 +226,17 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
copyFilesWithBlacklist("", from, to, blackList);
|
||||
}
|
||||
|
||||
private void doDownload(DownloadTaskParams param) throws IOException {
|
||||
downloadFile(param.url, param.zipFilePath);
|
||||
|
||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.zipFilePath)));
|
||||
ZipEntry ze;
|
||||
String filename;
|
||||
private void doFullPatch(DownloadTaskParams param) throws IOException {
|
||||
downloadFile(param);
|
||||
|
||||
removeDirectory(param.unzipDirectory);
|
||||
param.unzipDirectory.mkdirs();
|
||||
|
||||
while ((ze = zis.getNextEntry()) != null)
|
||||
{
|
||||
SafeZipFile zipFile = new SafeZipFile(param.targetFile);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry ze = entries.nextElement();
|
||||
|
||||
String fn = ze.getName();
|
||||
File fmd = new File(param.unzipDirectory, fn);
|
||||
|
||||
@@ -260,22 +249,25 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
continue;
|
||||
}
|
||||
|
||||
unzipToFile(zis, fmd);
|
||||
zipFile.unzipToFile(ze, fmd);
|
||||
}
|
||||
|
||||
zis.close();
|
||||
zipFile.close();
|
||||
|
||||
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Unzip finished");
|
||||
}
|
||||
}
|
||||
|
||||
private void copyFromResource(HashMap<String, ArrayList<File> > map) throws IOException {
|
||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(context.getPackageResourcePath())));
|
||||
ZipEntry ze;
|
||||
while ((ze = zis.getNextEntry()) != null) {
|
||||
private void copyFromResource(HashMap<String, ArrayList<File> > resToCopy) throws IOException {
|
||||
SafeZipFile zipFile = new SafeZipFile(new File(context.getPackageResourcePath()));
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry ze = entries.nextElement();
|
||||
|
||||
String fn = ze.getName();
|
||||
ArrayList<File> targets = map.get(fn);
|
||||
ArrayList<File> targets = resToCopy.get(fn);
|
||||
if (targets != null) {
|
||||
File lastTarget = null;
|
||||
for (File target: targets) {
|
||||
@@ -285,34 +277,35 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
if (lastTarget != null) {
|
||||
copyFile(lastTarget, target);
|
||||
} else {
|
||||
unzipToFile(zis, target);
|
||||
zipFile.unzipToFile(ze, target);
|
||||
lastTarget = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
zipFile.close();
|
||||
}
|
||||
|
||||
private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException {
|
||||
downloadFile(param.url, param.zipFilePath);
|
||||
|
||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.zipFilePath)));
|
||||
ZipEntry ze;
|
||||
int count;
|
||||
String filename;
|
||||
downloadFile(param);
|
||||
|
||||
removeDirectory(param.unzipDirectory);
|
||||
param.unzipDirectory.mkdirs();
|
||||
|
||||
HashMap<String, ArrayList<File>> copyList = new HashMap<String, ArrayList<File>>();
|
||||
|
||||
while ((ze = zis.getNextEntry()) != null)
|
||||
{
|
||||
boolean foundDiff = false;
|
||||
boolean foundBundlePatch = false;
|
||||
|
||||
SafeZipFile zipFile = new SafeZipFile(param.targetFile);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry ze = entries.nextElement();
|
||||
String fn = ze.getName();
|
||||
|
||||
if (fn.equals("__diff.json")) {
|
||||
foundDiff = true;
|
||||
// copy files from assets
|
||||
byte[] bytes = readBytes(zis);
|
||||
byte[] bytes = readBytes(zipFile.getInputStream(ze));
|
||||
String json = new String(bytes, "UTF-8");
|
||||
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
||||
|
||||
@@ -337,8 +330,9 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
continue;
|
||||
}
|
||||
if (fn.equals("index.bundlejs.patch")) {
|
||||
// do bsdiff patch
|
||||
byte[] patched = bsdiffPatch(readOriginBundle(), readBytes(zis));
|
||||
foundBundlePatch = true;
|
||||
|
||||
byte[] patched = hdiffPatch(readOriginBundle(), readBytes(zipFile.getInputStream(ze)));
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs"));
|
||||
fout.write(patched);
|
||||
@@ -356,10 +350,18 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
continue;
|
||||
}
|
||||
|
||||
unzipToFile(zis, fmd);
|
||||
zipFile.unzipToFile(ze, fmd);
|
||||
}
|
||||
|
||||
zis.close();
|
||||
zipFile.close();
|
||||
|
||||
|
||||
if (!foundDiff) {
|
||||
throw new Error("diff.json not found");
|
||||
}
|
||||
if (!foundBundlePatch) {
|
||||
throw new Error("bundle patch not found");
|
||||
}
|
||||
|
||||
copyFromResource(copyList);
|
||||
|
||||
@@ -370,23 +372,27 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
}
|
||||
|
||||
private void doPatchFromPpk(DownloadTaskParams param) throws IOException, JSONException {
|
||||
downloadFile(param.url, param.zipFilePath);
|
||||
|
||||
ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.zipFilePath)));
|
||||
ZipEntry ze;
|
||||
int count;
|
||||
String filename;
|
||||
downloadFile(param);
|
||||
|
||||
removeDirectory(param.unzipDirectory);
|
||||
param.unzipDirectory.mkdirs();
|
||||
|
||||
while ((ze = zis.getNextEntry()) != null)
|
||||
{
|
||||
int count;
|
||||
String filename;
|
||||
boolean foundDiff = false;
|
||||
boolean foundBundlePatch = false;
|
||||
|
||||
|
||||
SafeZipFile zipFile = new SafeZipFile(param.targetFile);
|
||||
Enumeration<? extends ZipEntry> entries = zipFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry ze = entries.nextElement();
|
||||
String fn = ze.getName();
|
||||
|
||||
if (fn.equals("__diff.json")) {
|
||||
foundDiff = true;
|
||||
// copy files from assets
|
||||
byte[] bytes = readBytes(zis);
|
||||
byte[] bytes = readBytes(zipFile.getInputStream(ze));
|
||||
String json = new String(bytes, "UTF-8");
|
||||
JSONObject obj = (JSONObject)new JSONTokener(json).nextValue();
|
||||
|
||||
@@ -405,8 +411,8 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
continue;
|
||||
}
|
||||
if (fn.equals("index.bundlejs.patch")) {
|
||||
// do bsdiff patch
|
||||
byte[] patched = bsdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis));
|
||||
foundBundlePatch = true;
|
||||
byte[] patched = hdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zipFile.getInputStream(ze)));
|
||||
|
||||
FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs"));
|
||||
fout.write(patched);
|
||||
@@ -424,11 +430,17 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
continue;
|
||||
}
|
||||
|
||||
unzipToFile(zis, fmd);
|
||||
zipFile.unzipToFile(ze, fmd);
|
||||
}
|
||||
|
||||
zis.close();
|
||||
zipFile.close();
|
||||
|
||||
if (!foundDiff) {
|
||||
throw new Error("diff.json not found");
|
||||
}
|
||||
if (!foundBundlePatch) {
|
||||
throw new Error("bundle patch not found");
|
||||
}
|
||||
if (UpdateContext.DEBUG) {
|
||||
Log.d("RNUpdate", "Unzip finished");
|
||||
}
|
||||
@@ -455,10 +467,11 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(DownloadTaskParams... params) {
|
||||
int taskType = params[0].type;
|
||||
try {
|
||||
switch (params[0].type) {
|
||||
case DownloadTaskParams.TASK_TYPE_FULL_DOWNLOAD:
|
||||
doDownload(params[0]);
|
||||
switch (taskType) {
|
||||
case DownloadTaskParams.TASK_TYPE_PATCH_FULL:
|
||||
doFullPatch(params[0]);
|
||||
break;
|
||||
case DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK:
|
||||
doPatchFromApk(params[0]);
|
||||
@@ -466,16 +479,45 @@ class DownloadTask extends AsyncTask<DownloadTaskParams, long[], Void> {
|
||||
case DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK:
|
||||
doPatchFromPpk(params[0]);
|
||||
break;
|
||||
case DownloadTaskParams.TASK_TYPE_CLEARUP:
|
||||
case DownloadTaskParams.TASK_TYPE_CLEANUP:
|
||||
doCleanUp(params[0]);
|
||||
break;
|
||||
case DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD:
|
||||
downloadFile(params[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (params[0].listener != null) {
|
||||
params[0].listener.onDownloadCompleted(params[0]);
|
||||
}
|
||||
params[0].listener.onDownloadCompleted();
|
||||
} catch (Throwable e) {
|
||||
if (UpdateContext.DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
params[0].listener.onDownloadFailed(e);
|
||||
switch (taskType) {
|
||||
case DownloadTaskParams.TASK_TYPE_PATCH_FULL:
|
||||
case DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK:
|
||||
case DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK:
|
||||
try {
|
||||
removeDirectory(params[0].unzipDirectory);
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD:
|
||||
// if (targetToClean.exists()) {
|
||||
params[0].targetFile.delete();
|
||||
// }
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Log.e("pushy", "download task failed", e);
|
||||
|
||||
if (params[0].listener != null) {
|
||||
params[0].listener.onDownloadFailed(e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@@ -8,17 +8,19 @@ import java.io.File;
|
||||
* Created by tdzl2003 on 3/31/16.
|
||||
*/
|
||||
class DownloadTaskParams {
|
||||
static final int TASK_TYPE_FULL_DOWNLOAD = 1;
|
||||
static final int TASK_TYPE_PATCH_FROM_APK = 2;
|
||||
static final int TASK_TYPE_PATCH_FROM_PPK = 3;
|
||||
static final int TASK_TYPE_CLEANUP = 0; //Keep hash & originHash
|
||||
|
||||
static final int TASK_TYPE_PATCH_FULL = 1;
|
||||
static final int TASK_TYPE_PATCH_FROM_APK = 2;
|
||||
static final int TASK_TYPE_PATCH_FROM_PPK = 3;
|
||||
static final int TASK_TYPE_PLAIN_DOWNLOAD = 4;
|
||||
|
||||
static final int TASK_TYPE_CLEARUP = 0; //Keep hash & originHash
|
||||
|
||||
int type;
|
||||
String url;
|
||||
String hash;
|
||||
String originHash;
|
||||
File zipFilePath;
|
||||
File targetFile;
|
||||
File unzipDirectory;
|
||||
File originDirectory;
|
||||
UpdateContext.DownloadFileListener listener;
|
||||
|
@@ -0,0 +1,14 @@
|
||||
package cn.reactnative.modules.update;
|
||||
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
/**
|
||||
* Providing a custom {@code FileProvider} prevents manifest {@code <provider>} name collisions.
|
||||
*
|
||||
* See https://developer.android.com/guide/topics/manifest/provider-element.html for details.
|
||||
*/
|
||||
public class PushyFileProvider extends FileProvider {
|
||||
|
||||
// This class intentionally left blank.
|
||||
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
package cn.reactnative.modules.update;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class SafeZipFile extends ZipFile {
|
||||
|
||||
public SafeZipFile(File file) throws IOException {
|
||||
super(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enumeration<? extends ZipEntry> entries() {
|
||||
return new SafeZipEntryIterator(super.entries());
|
||||
}
|
||||
|
||||
private static class SafeZipEntryIterator implements Enumeration<ZipEntry> {
|
||||
|
||||
final private Enumeration<? extends ZipEntry> delegate;
|
||||
|
||||
private SafeZipEntryIterator(Enumeration<? extends ZipEntry> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMoreElements() {
|
||||
return delegate.hasMoreElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZipEntry nextElement() {
|
||||
ZipEntry entry = delegate.nextElement();
|
||||
if (null != entry) {
|
||||
String name = entry.getName();
|
||||
/**
|
||||
* avoid ZipperDown
|
||||
*/
|
||||
if (null != name && (name.contains("../") || name.contains("..\\"))) {
|
||||
throw new SecurityException("illegal entry: " + entry.getName());
|
||||
}
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
public void unzipToFile(ZipEntry entry, File output) throws IOException {
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = getInputStream(entry);
|
||||
writeOutInputStream(output, inputStream);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeOutInputStream(File file, InputStream inputStream) throws IOException {
|
||||
BufferedOutputStream output = null;
|
||||
try {
|
||||
output = new BufferedOutputStream(
|
||||
new FileOutputStream(file));
|
||||
BufferedInputStream input = new BufferedInputStream(inputStream);
|
||||
byte b[] = new byte[8192];
|
||||
int n;
|
||||
while ((n = input.read(b, 0, 8192)) >= 0) {
|
||||
output.write(b, 0, n);
|
||||
}
|
||||
} finally {
|
||||
if (output != null) {
|
||||
output.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,23 +4,27 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Created by tdzl2003 on 3/31/16.
|
||||
*/
|
||||
public class UpdateContext {
|
||||
private Context context;
|
||||
private File rootDir;
|
||||
private Executor executor;
|
||||
|
||||
public static boolean DEBUG = false;
|
||||
private static ReactInstanceManager mReactInstanceManager;
|
||||
private static boolean isUsingBundleUrl = false;
|
||||
|
||||
public UpdateContext(Context context) {
|
||||
this.context = context;
|
||||
@@ -41,7 +45,7 @@ public class UpdateContext {
|
||||
editor.putString("packageVersion", packageVersion);
|
||||
editor.apply();
|
||||
|
||||
this.clearUp();
|
||||
this.cleanUp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,61 +69,107 @@ public class UpdateContext {
|
||||
return context.getString(R.string.pushy_build_time);
|
||||
}
|
||||
|
||||
public Map getBlockUpdate() {
|
||||
return new HashMap<String, Object>() {{
|
||||
put("until", sp.getInt("blockUntil", 0));
|
||||
put("reason", sp.getString("blockReason", null));
|
||||
}};
|
||||
}
|
||||
|
||||
public boolean getIsUsingBundleUrl() {
|
||||
return isUsingBundleUrl;
|
||||
}
|
||||
|
||||
public interface DownloadFileListener {
|
||||
void onDownloadCompleted();
|
||||
void onDownloadCompleted(DownloadTaskParams params);
|
||||
void onDownloadFailed(Throwable error);
|
||||
}
|
||||
|
||||
public void downloadFile(String url, String hashName, DownloadFileListener listener) {
|
||||
public void downloadFullUpdate(String url, String hash, DownloadFileListener listener) {
|
||||
DownloadTaskParams params = new DownloadTaskParams();
|
||||
params.type = DownloadTaskParams.TASK_TYPE_FULL_DOWNLOAD;
|
||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FULL;
|
||||
params.url = url;
|
||||
params.hash = hashName;
|
||||
params.hash = hash;
|
||||
params.listener = listener;
|
||||
params.zipFilePath = new File(rootDir, hashName + ".ppk");
|
||||
params.unzipDirectory = new File(rootDir, hashName);
|
||||
params.targetFile = new File(rootDir, hash + ".ppk");
|
||||
params.unzipDirectory = new File(rootDir, hash);
|
||||
new DownloadTask(context).executeOnExecutor(this.executor, params);
|
||||
}
|
||||
|
||||
public void downloadPatchFromApk(String url, String hashName, DownloadFileListener listener) {
|
||||
public void downloadFile(String url, String hash, String fileName, DownloadFileListener listener) {
|
||||
DownloadTaskParams params = new DownloadTaskParams();
|
||||
params.type = DownloadTaskParams.TASK_TYPE_PLAIN_DOWNLOAD;
|
||||
params.url = url;
|
||||
params.hash = hash;
|
||||
params.listener = listener;
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N && fileName.equals("update.apk")) {
|
||||
params.targetFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "pushy_update.apk");
|
||||
|
||||
} else {
|
||||
params.targetFile = new File(rootDir, fileName);
|
||||
|
||||
}
|
||||
// params.unzipDirectory = new File(rootDir, hash);
|
||||
new DownloadTask(context).executeOnExecutor(this.executor, params);
|
||||
}
|
||||
|
||||
public void downloadPatchFromApk(String url, String hash, DownloadFileListener listener) {
|
||||
DownloadTaskParams params = new DownloadTaskParams();
|
||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK;
|
||||
params.url = url;
|
||||
params.hash = hashName;
|
||||
params.hash = hash;
|
||||
params.listener = listener;
|
||||
params.zipFilePath = new File(rootDir, hashName + ".apk.patch");
|
||||
params.unzipDirectory = new File(rootDir, hashName);
|
||||
params.targetFile = new File(rootDir, hash + ".apk.patch");
|
||||
params.unzipDirectory = new File(rootDir, hash);
|
||||
new DownloadTask(context).executeOnExecutor(this.executor, params);
|
||||
}
|
||||
|
||||
public void downloadPatchFromPpk(String url, String hashName, String originHashName, DownloadFileListener listener) {
|
||||
public void downloadPatchFromPpk(String url, String hash, String originHash, DownloadFileListener listener) {
|
||||
DownloadTaskParams params = new DownloadTaskParams();
|
||||
params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK;
|
||||
params.url = url;
|
||||
params.hash = hashName;
|
||||
params.originHash = originHashName;
|
||||
params.hash = hash;
|
||||
params.originHash = originHash;
|
||||
params.listener = listener;
|
||||
params.zipFilePath = new File(rootDir, originHashName + "-" + hashName + ".ppk.patch");
|
||||
params.unzipDirectory = new File(rootDir, hashName);
|
||||
params.originDirectory = new File(rootDir, originHashName);
|
||||
params.targetFile = new File(rootDir, originHash + "-" + hash + ".ppk.patch");
|
||||
params.unzipDirectory = new File(rootDir, hash);
|
||||
params.originDirectory = new File(rootDir, originHash);
|
||||
new DownloadTask(context).executeOnExecutor(this.executor, params);
|
||||
}
|
||||
|
||||
private SharedPreferences sp;
|
||||
|
||||
public void switchVersion(String hashName) {
|
||||
if (!new File(rootDir, hashName+"/index.bundlejs").exists()) {
|
||||
throw new Error("Bundle version " + hashName + " not found.");
|
||||
public void switchVersion(String hash) {
|
||||
if (!new File(rootDir, hash+"/index.bundlejs").exists()) {
|
||||
throw new Error("Bundle version " + hash + " not found.");
|
||||
}
|
||||
String lastVersion = getCurrentVersion();
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString("currentVersion", hashName);
|
||||
if (lastVersion != null) {
|
||||
editor.putString("currentVersion", hash);
|
||||
if (lastVersion != null && !lastVersion.equals(hash)) {
|
||||
editor.putString("lastVersion", lastVersion);
|
||||
}
|
||||
editor.putBoolean("firstTime", true);
|
||||
editor.putBoolean("firstTimeOk", false);
|
||||
editor.putBoolean("rolledBack", false);
|
||||
editor.putString("rolledBackVersion", null);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public void setKv(String key, String value) {
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putString(key, value);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public String getKv(String key) {
|
||||
return sp.getString(key, null);
|
||||
}
|
||||
|
||||
public void setBlockUpdate(int until, String reason) {
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putInt("blockUntil", until);
|
||||
editor.putString("blockReason", reason);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@@ -131,17 +181,22 @@ public class UpdateContext {
|
||||
return sp.getBoolean("firstTime", false);
|
||||
}
|
||||
|
||||
public boolean isRolledBack() {
|
||||
return sp.getBoolean("rolledBack", false);
|
||||
public String rolledBackVersion() {
|
||||
return sp.getString("rolledBackVersion", null);
|
||||
}
|
||||
|
||||
public void markSuccess() {
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putBoolean("firstTimeOk", true);
|
||||
editor.remove("lastVersion");
|
||||
String lastVersion = sp.getString("lastVersion", null);
|
||||
String curVersion = sp.getString("currentVersion", null);
|
||||
if (lastVersion != null && !lastVersion.equals(curVersion)) {
|
||||
editor.remove("lastVersion");
|
||||
editor.remove("hash_" + lastVersion);
|
||||
}
|
||||
editor.apply();
|
||||
|
||||
this.clearUp();
|
||||
this.cleanUp();
|
||||
}
|
||||
|
||||
public void clearFirstTime() {
|
||||
@@ -149,15 +204,24 @@ public class UpdateContext {
|
||||
editor.putBoolean("firstTime", false);
|
||||
editor.apply();
|
||||
|
||||
this.clearUp();
|
||||
this.cleanUp();
|
||||
}
|
||||
|
||||
public void clearRollbackMark() {
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.putBoolean("rolledBack", false);
|
||||
editor.putString("rolledBackVersion", null);
|
||||
editor.apply();
|
||||
|
||||
this.clearUp();
|
||||
this.cleanUp();
|
||||
}
|
||||
|
||||
|
||||
public static void setCustomInstanceManager(ReactInstanceManager instanceManager) {
|
||||
mReactInstanceManager = instanceManager;
|
||||
}
|
||||
|
||||
public ReactInstanceManager getCustomReactInstanceManager() {
|
||||
return mReactInstanceManager;
|
||||
}
|
||||
|
||||
public static String getBundleUrl(Context context) {
|
||||
@@ -173,6 +237,7 @@ public class UpdateContext {
|
||||
}
|
||||
|
||||
public String getBundleUrl(String defaultAssetsUrl) {
|
||||
isUsingBundleUrl = true;
|
||||
String currentVersion = getCurrentVersion();
|
||||
if (currentVersion == null) {
|
||||
return defaultAssetsUrl;
|
||||
@@ -200,6 +265,7 @@ public class UpdateContext {
|
||||
|
||||
private String rollBack() {
|
||||
String lastVersion = sp.getString("lastVersion", null);
|
||||
String currentVersion = sp.getString("currentVersion", null);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
if (lastVersion == null) {
|
||||
editor.remove("currentVersion");
|
||||
@@ -208,26 +274,17 @@ public class UpdateContext {
|
||||
}
|
||||
editor.putBoolean("firstTimeOk", true);
|
||||
editor.putBoolean("firstTime", false);
|
||||
editor.putBoolean("rolledBack", true);
|
||||
editor.putString("rolledBackVersion", currentVersion);
|
||||
editor.apply();
|
||||
return lastVersion;
|
||||
}
|
||||
|
||||
private void clearUp() {
|
||||
private void cleanUp() {
|
||||
DownloadTaskParams params = new DownloadTaskParams();
|
||||
params.type = DownloadTaskParams.TASK_TYPE_CLEARUP;
|
||||
params.type = DownloadTaskParams.TASK_TYPE_CLEANUP;
|
||||
params.hash = sp.getString("currentVersion", null);
|
||||
params.originHash = sp.getString("lastVersion", null);
|
||||
params.unzipDirectory = rootDir;
|
||||
params.listener = new DownloadFileListener() {
|
||||
@Override
|
||||
public void onDownloadCompleted() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFailed(Throwable error) {
|
||||
}
|
||||
};
|
||||
new DownloadTask(context).executeOnExecutor(this.executor, params);
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@ package cn.reactnative.modules.update;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
@@ -18,21 +20,21 @@ import com.facebook.react.bridge.JSBundleLoader;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by tdzl2003 on 3/31/16.
|
||||
*/
|
||||
public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
import static androidx.core.content.FileProvider.getUriForFile;
|
||||
|
||||
public class UpdateModule extends ReactContextBaseJavaModule {
|
||||
UpdateContext updateContext;
|
||||
public static ReactApplicationContext mContext;
|
||||
|
||||
public UpdateModule(ReactApplicationContext reactContext, UpdateContext updateContext) {
|
||||
super(reactContext);
|
||||
this.updateContext = updateContext;
|
||||
mContext=reactContext;
|
||||
mContext = reactContext;
|
||||
}
|
||||
|
||||
public UpdateModule(ReactApplicationContext reactContext) {
|
||||
@@ -46,16 +48,19 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
constants.put("packageVersion", updateContext.getPackageVersion());
|
||||
constants.put("currentVersion", updateContext.getCurrentVersion());
|
||||
constants.put("buildTime", updateContext.getBuildTime());
|
||||
constants.put("isUsingBundleUrl", updateContext.getIsUsingBundleUrl());
|
||||
boolean isFirstTime = updateContext.isFirstTime();
|
||||
constants.put("isFirstTime", isFirstTime);
|
||||
if (isFirstTime) {
|
||||
updateContext.clearFirstTime();
|
||||
}
|
||||
boolean isRolledBack = updateContext.isRolledBack();
|
||||
constants.put("isRolledBack", isRolledBack);
|
||||
if (isRolledBack) {
|
||||
String rolledBackVersion = updateContext.rolledBackVersion();
|
||||
constants.put("rolledBackVersion", rolledBackVersion);
|
||||
if (rolledBackVersion != null) {
|
||||
updateContext.clearRollbackMark();
|
||||
}
|
||||
constants.put("blockUpdate", updateContext.getBlockUpdate());
|
||||
constants.put("uuid", updateContext.getKv("uuid"));
|
||||
return constants;
|
||||
}
|
||||
|
||||
@@ -65,12 +70,12 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void downloadUpdate(ReadableMap options, final Promise promise){
|
||||
public void downloadUpdate(ReadableMap options, final Promise promise) {
|
||||
String url = options.getString("updateUrl");
|
||||
String hash = options.getString("hashName");
|
||||
updateContext.downloadFile(url, hash, new UpdateContext.DownloadFileListener() {
|
||||
String hash = options.getString("hash");
|
||||
updateContext.downloadFullUpdate(url, hash, new UpdateContext.DownloadFileListener() {
|
||||
@Override
|
||||
public void onDownloadCompleted() {
|
||||
public void onDownloadCompleted(DownloadTaskParams params) {
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@@ -82,12 +87,57 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void downloadPatchFromPackage(ReadableMap options, final Promise promise){
|
||||
public void downloadAndInstallApk(ReadableMap options, final Promise promise) {
|
||||
String url = options.getString("url");
|
||||
String hash = options.getString("hash");
|
||||
String target = options.getString("target");
|
||||
updateContext.downloadFile(url, hash, target, new UpdateContext.DownloadFileListener() {
|
||||
@Override
|
||||
public void onDownloadCompleted(DownloadTaskParams params) {
|
||||
installApk(params.targetFile);
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFailed(Throwable error) {
|
||||
promise.reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// install downloaded apk
|
||||
@ReactMethod
|
||||
public static void installApk(String url) {
|
||||
File toInstall = new File(url);
|
||||
installApk(toInstall);
|
||||
}
|
||||
|
||||
public static void installApk(File toInstall) {
|
||||
Uri apkUri;
|
||||
Intent intent;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
apkUri = getUriForFile(mContext, mContext.getPackageName() + ".pushy.fileprovider", toInstall);
|
||||
intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
|
||||
intent.setData(apkUri);
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
} else {
|
||||
apkUri = Uri.fromFile(toInstall);
|
||||
intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
private void downloadPatchFromPackage(ReadableMap options, final Promise promise) {
|
||||
String url = options.getString("updateUrl");
|
||||
String hash = options.getString("hashName");
|
||||
String hash = options.getString("hash");
|
||||
|
||||
updateContext.downloadPatchFromApk(url, hash, new UpdateContext.DownloadFileListener() {
|
||||
@Override
|
||||
public void onDownloadCompleted() {
|
||||
public void onDownloadCompleted(DownloadTaskParams params) {
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@@ -97,15 +147,17 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ReactMethod
|
||||
public void downloadPatchFromPpk(ReadableMap options, final Promise promise){
|
||||
private void downloadPatchFromPpk(ReadableMap options, final Promise promise) {
|
||||
String url = options.getString("updateUrl");
|
||||
String hash = options.getString("hashName");
|
||||
String originHash = options.getString("originHashName");
|
||||
String hash = options.getString("hash");
|
||||
|
||||
String originHash = options.getString("originHash");
|
||||
|
||||
updateContext.downloadPatchFromPpk(url, hash, originHash, new UpdateContext.DownloadFileListener() {
|
||||
@Override
|
||||
public void onDownloadCompleted() {
|
||||
public void onDownloadCompleted(DownloadTaskParams params) {
|
||||
promise.resolve(null);
|
||||
}
|
||||
|
||||
@@ -118,7 +170,7 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
|
||||
@ReactMethod
|
||||
public void reloadUpdate(ReadableMap options) {
|
||||
final String hash = options.getString("hashName");
|
||||
final String hash = options.getString("hash");
|
||||
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
@@ -127,22 +179,26 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
updateContext.switchVersion(hash);
|
||||
Activity activity = getCurrentActivity();
|
||||
Application application = activity.getApplication();
|
||||
ReactInstanceManager instanceManager = ((ReactApplication) application).getReactNativeHost().getReactInstanceManager();
|
||||
ReactInstanceManager instanceManager = updateContext.getCustomReactInstanceManager();
|
||||
|
||||
if (instanceManager == null) {
|
||||
instanceManager = ((ReactApplication) application).getReactNativeHost().getReactInstanceManager();
|
||||
}
|
||||
|
||||
try {
|
||||
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
|
||||
jsBundleField.setAccessible(true);
|
||||
jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application));
|
||||
} catch (Throwable err) {
|
||||
JSBundleLoader loader = JSBundleLoader.createFileLoader(UpdateContext.getBundleUrl(application));
|
||||
Field loadField = instanceManager.getClass().getDeclaredField("mBundleLoader");
|
||||
loadField.setAccessible(true);
|
||||
loadField.set(instanceManager, loader);
|
||||
} catch (Throwable err) {
|
||||
Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile");
|
||||
jsBundleField.setAccessible(true);
|
||||
jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application));
|
||||
}
|
||||
|
||||
try {
|
||||
instanceManager.recreateReactContextInBackground();
|
||||
} catch(Throwable err) {
|
||||
} catch (Throwable err) {
|
||||
activity.recreate();
|
||||
}
|
||||
|
||||
@@ -155,7 +211,7 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
|
||||
@ReactMethod
|
||||
public void setNeedUpdate(ReadableMap options) {
|
||||
final String hash = options.getString("hashName");
|
||||
final String hash = options.getString("hash");
|
||||
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
@@ -179,8 +235,55 @@ public class UpdateModule extends ReactContextBaseJavaModule{
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setBlockUpdate(ReadableMap options) {
|
||||
final int until = options.getInt("until");
|
||||
final String reason = options.getString("reason");
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateContext.setBlockUpdate(until, reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setUuid(final String uuid) {
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateContext.setKv("uuid", uuid);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setLocalHashInfo(final String hash, final String info) {
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateContext.setKv("hash_" + hash, info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getLocalHashInfo(final String hash, final Promise promise) {
|
||||
promise.resolve(updateContext.getKv("hash_" + hash));
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void addListener(String eventName) {
|
||||
// Set up any upstream listeners or background tasks as necessary
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void removeListeners(Integer count) {
|
||||
// Remove upstream listeners, stop unnecessary background tasks
|
||||
}
|
||||
|
||||
/* 发送事件*/
|
||||
public static void sendEvent(String eventName, WritableMap params) {
|
||||
public static void sendEvent(String eventName, WritableMap params) {
|
||||
((ReactContext) mContext).getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName,
|
||||
params);
|
||||
}
|
||||
|
5
android/src/main/res/xml/pushy_file_paths.xml
Normal file
5
android/src/main/res/xml/pushy_file_paths.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<files-path
|
||||
name="pushy"
|
||||
path="." />
|
||||
</paths>
|
@@ -1,53 +0,0 @@
|
||||
# react-native-update [](http://badge.fury.io/js/react-native-update)
|
||||
|
||||
本组件是面向 React Native 提供热更新功能的组件,请结合[Update 服务](https://update.reactnative.cn/)使用。
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
注意,在 iOS 上使用热更新有被拒的可能。被拒之后可以按此步骤单独屏蔽 iOS 端(`react-native-update`版本需 >= 5.3.2):
|
||||
</summary>
|
||||
|
||||
1. 如果 RN 版本>=0.60,在项目根目录下编辑或创建 react-native.config.js,添加如下内容
|
||||
|
||||
```js
|
||||
// react-native.config.js
|
||||
module.exports = {
|
||||
dependencies: {
|
||||
'react-native-update': {
|
||||
platforms: {
|
||||
ios: null, // 阻止ios模块自动链接
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
2. 如果在原生代码端尚未配置,则跳过下面文档中的 ios 端的配置。如果已经配置,则按文档的步骤反向操作(添加的 ios 代码删去)。
|
||||
3. 如果是 0.60 以上版本或使用了 cocoapods,在 ios 目录中再次运行 pod install,确保 Podfile 和 Podfile.lock 中都没有'react-native-update'。如果 RN 版本<0.60,则运行`react-native unlink react-native-update`。
|
||||
4. 在 js 代码里调用 checkUpdate()方法前,判断 Platform.OS,如果是 ios 平台则直接 return 跳过。
|
||||
</details>
|
||||
|
||||
### 优势
|
||||
|
||||
1. 命令行工具&网页双端管理,版本发布过程简单便捷,完全可以集成 CI。
|
||||
2. 基于 bsdiff 算法创建的**超小更新包**,通常版本迭代后在 1-10KB 之间,避免数百 KB 的流量消耗。
|
||||
3. 支持崩溃回滚,安全可靠。
|
||||
4. meta 信息及开放 API,提供更高扩展性。
|
||||
5. 跨越多个版本进行更新时,只需要下载**一个更新包**,不需要逐版本依次更新。
|
||||
|
||||
### 本地开发
|
||||
|
||||
```
|
||||
$ git clone git@github.com:reactnativecn/react-native-pushy.git
|
||||
$ cd react-native-pushy/Example/testHotUpdate
|
||||
$ yarn
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
本地库文件使用 yarn link 链接,因此可直接在源文件中修改,在 testHotUpdate 项目中调试。
|
||||
|
||||
### 关于我们
|
||||
|
||||
本组件由[React Native 中文网](https://reactnative.cn/)独家发布,如有定制需求可以[联系我们](https://reactnative.cn/about.html#content)。
|
||||
|
||||
关于此插件发现任何问题,可以前往[Issues](https://github.com/reactnativecn/react-native-pushy/issues)或者[中文社区](http://bbs.reactnative.cn/category/7)发帖提问。
|
@@ -1,10 +0,0 @@
|
||||
- 安装与快速入门
|
||||
|
||||
- [准备工作](guide.md)
|
||||
- [添加热更新功能](guide2.md)
|
||||
- [发布版本](guide3.md)
|
||||
- [常见问题与高级指南](faq_advance.md)
|
||||
|
||||
- [API接口](api.md)
|
||||
- [命令行工具](cli.md)
|
||||
- [最近更新](changelog.md)
|
66
docs/api.md
66
docs/api.md
@@ -1,66 +0,0 @@
|
||||
# API
|
||||
|
||||
### downloadRootDir
|
||||
|
||||
下载的根目录。你可以使用react-native-fs等第三方组件检查其中的内容。
|
||||
|
||||
### packageVersion
|
||||
|
||||
当前应用包的版本名。
|
||||
|
||||
### currentVersion
|
||||
|
||||
当前版本的Hash号。
|
||||
|
||||
### isFirstTime
|
||||
|
||||
是否更新后的首次启动。当此项为真时,你需要在合适的时候调用`markSuccess()`以确保更新成功。否则应用下一次启动时将会回滚。
|
||||
|
||||
### isRolledBack
|
||||
|
||||
是否刚刚经历了一次回滚。
|
||||
|
||||
### async function checkUpdate(appKey)
|
||||
|
||||
检查更新,返回值有三种情形:
|
||||
|
||||
1. `{expired: true}`:该应用包(原生部分)已过期,需要前往应用市场下载新的版本。
|
||||
```
|
||||
{
|
||||
expired: true,
|
||||
downloadUrl: 'http://appstore/downloadUrl',
|
||||
}
|
||||
```
|
||||
2. `{upToDate: true}`:当前已经更新到最新,无需进行更新。
|
||||
|
||||
3. `{update: true}`:当前有新版本可以更新。info的`name`、`description`字段可
|
||||
以用于提示用户,而`metaInfo`字段则可以根据你的需求自定义其它属性(如是否静默更新、
|
||||
是否强制更新等等)。另外还有几个字段,包含了完整更新包或补丁包的下载地址,
|
||||
```
|
||||
{
|
||||
update: true,
|
||||
name: '1.0.3-rc',
|
||||
hash: 'hash',
|
||||
description: '添加聊天功能\n修复商城页面BUG',
|
||||
metaInfo: '{"silent":true}',
|
||||
updateUrl: 'http://update-packages.reactnative.cn/hash',
|
||||
pdiffUrl: 'http://update-packages.reactnative.cn/hash',
|
||||
diffUrl: 'http://update-packages.reactnative.cn/hash',
|
||||
}
|
||||
```
|
||||
|
||||
### async function downloadUpdate(info)
|
||||
|
||||
下载更新版本。info为checkUpdate函数的返回值,并且仅当`update:true`时实际进行下载。
|
||||
|
||||
### function switchVersion(hash)
|
||||
|
||||
立即重启应用,并加载已经下载完毕的版本。
|
||||
|
||||
### function switchVersionLater(hash)
|
||||
|
||||
在下一次启动应用的时候加载已经下载完毕的版本。
|
||||
|
||||
### function markSuccess()
|
||||
|
||||
在isFirstTime为true时需在应用成功启动后调用此函数,
|
@@ -1,73 +0,0 @@
|
||||
### 最近更新
|
||||
|
||||
## 5.5.3 (2019-12-18)
|
||||
|
||||
1. 忽略hermes的输出避免buffer溢出
|
||||
|
||||
## 5.5.2 (2019-12-06)
|
||||
|
||||
1. 修复使用use_frameworks时无法读取时间戳的问题
|
||||
|
||||
## 5.5.0 (2019-11-24)
|
||||
|
||||
1. 打包时加入时间戳
|
||||
|
||||
## 5.4.0 (2019-11-16)
|
||||
|
||||
1. 修改类名方法名
|
||||
|
||||
## 5.3.2 (2019-10-25)
|
||||
|
||||
1. 可以禁用ios端以避免审核被拒
|
||||
|
||||
## 5.3.0 (2019-09-19)
|
||||
|
||||
1. 替换 apk reader 以避免某些环境读取 apk 版本号报错的问题
|
||||
|
||||
## 5.2.9 (2019-09-18)
|
||||
|
||||
1. 添加 proguard 混淆规则以解决开启混淆后闪退的问题
|
||||
|
||||
## 5.2.8
|
||||
|
||||
1. 解决某些情形下 Android 调用 switchVersion 不能重启的问题
|
||||
|
||||
## 5.2.7
|
||||
|
||||
1. 改进 windows 端打更新包的兼容性(部分 windows 机器上会产生空 ppk 文件)
|
||||
|
||||
## 5.2.4
|
||||
|
||||
1. 支持 RN 0.61 的 hermes(路径变化)
|
||||
2. iOS 端使用第三方的 SSZipArchive 以减少重名冲突
|
||||
|
||||
## 5.2.2
|
||||
|
||||
1. 修复一处导致 iOS 回滚的问题
|
||||
|
||||
## 5.2.1
|
||||
|
||||
1. 检测如果开启了 hermes,则自动编译为 hermes 字节码格式
|
||||
|
||||
## 5.2.0
|
||||
|
||||
1. 添加 typescript 声明
|
||||
2. 支持 cocoapods
|
||||
|
||||
## 5.1.9
|
||||
|
||||
1. 重写 bundle 命令以提升版本兼容性
|
||||
2. 改进命令行的输出样式
|
||||
|
||||
## 5.1.8
|
||||
|
||||
1. 服务器迁移到 https
|
||||
2. android 支持 64 位
|
||||
|
||||
## 5.1.6
|
||||
|
||||
解决 Android 热更新后部分图片丢失问题:
|
||||
|
||||
同一个项目中放置了多个完全相同的文件,在 5.1.0 至 5.1.5 之间的版本中,更新后有时会出现其中的部分无法显示。此问题在 5.1.6 版本修复。
|
||||
|
||||
修复此问题涉及原生部分,需要重新打包。
|
118
docs/cli.md
118
docs/cli.md
@@ -1,118 +0,0 @@
|
||||
# 命令行工具
|
||||
|
||||
## 安装
|
||||
|
||||
```
|
||||
$ npm install -g react-native-update-cli
|
||||
$ npm install --save react-native-update
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
#### pushy bundle
|
||||
|
||||
生成资源包
|
||||
|
||||
* platform: ios|android 对应的平台
|
||||
* entryFile: 入口脚本文件
|
||||
* intermediaDir: 临时文件输出目录
|
||||
* output: 最终ppk文件输出路径
|
||||
* dev: 是否打包开发版本
|
||||
* verbose: 是否展现打包过程的详细信息
|
||||
|
||||
#### pushy diff <origin> <next>
|
||||
|
||||
提供两个ppk文件,生成从origin到next版本的差异更新包。
|
||||
|
||||
* output: diff文件输出路径
|
||||
|
||||
#### pushy diffFromApk <apkFile> <next>
|
||||
|
||||
提供一个apk文件和一个ppk文件,生成从apk文件到next版本的差异更新包。
|
||||
|
||||
如果使用热更新开放平台,你不需要自己执行此命令。
|
||||
|
||||
* output: diff文件输出路径
|
||||
|
||||
#### pushy diffFromIpa <ipaFile> <next>
|
||||
|
||||
提供一个ipa文件和一个ppk文件,生成从ipa文件到next版本的差异更新包。
|
||||
|
||||
如果使用热更新开放平台,你不需要自己执行此命令。
|
||||
|
||||
* output: diff文件输出路径
|
||||
|
||||
#### pushy login [<email>] [<pwd>]
|
||||
|
||||
登录热更新开放平台。你需要先登录才能使用下面的命令。
|
||||
|
||||
#### pushy logout
|
||||
|
||||
登出并清除本地的登录信息
|
||||
|
||||
#### pushy me
|
||||
|
||||
查看自己是否已经登录,以及昵称等信息。
|
||||
|
||||
#### pushy createApp
|
||||
|
||||
创建应用并立刻绑定到当前工程。这项操作也可以在网页管理端进行。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
- name: 应用名称
|
||||
- downloadUrl: 应用安装包的下载地址
|
||||
|
||||
#### pushy deleteApp [appId]
|
||||
|
||||
删除已有应用。所有已创建的应用包、热更新版本都会被同时删除。这项操作也可以在网页管理端进行。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
|
||||
#### pushy apps
|
||||
|
||||
查看当前已创建的全部应用。这项操作也可以在网页管理端进行。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
|
||||
#### pushy selectApp [appId]
|
||||
|
||||
绑定应用到当前工程。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
|
||||
#### pushy uploadIpa <ipaFile>
|
||||
|
||||
上传 ipa 文件到开放平台。
|
||||
|
||||
#### pushy uploadApk <apkFile>
|
||||
|
||||
上传 apk 文件到开放平台。
|
||||
|
||||
#### pushy packages
|
||||
|
||||
查看已经上传的包。这项操作也可以在网页管理端进行。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
|
||||
#### pushy publish <ppkFile>
|
||||
|
||||
发布新的更新版本。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
- name: 当前版本的名字(版本号)
|
||||
- description: 当前版本的描述信息,可以对用户进行展示
|
||||
- metaInfo: 当前版本的元信息,可以用来保存一些额外信息
|
||||
|
||||
#### pushy versions
|
||||
|
||||
分页列举可用的版本。这项操作也可以在网页管理端进行。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
|
||||
#### pushy update
|
||||
|
||||
为一个包版本绑定一个更新版本。这项操作也可以在网页管理端进行。
|
||||
|
||||
- platform: ios|android 对应的平台
|
||||
- versionId: 要绑定的版本 ID
|
||||
- packageId: 要绑定的包 ID
|
@@ -1,71 +0,0 @@
|
||||
## 常见问题
|
||||
|
||||
#### 报错 NDK not configured.
|
||||
|
||||
你需要下载并安装NDK,然后设置到环境变量`ANDROID_NDK_HOME`中。
|
||||
|
||||
#### 报错 Execution failed for task ':react-native-update:compileReleaseNdk'
|
||||
参看 https://github.com/reactnativecn/react-native-pushy/issues/64#issuecomment-287967742
|
||||
|
||||
#### iOS报错 Unable to execute JS call: __fbBatchedBridge is undefined
|
||||
|
||||
如果直接修改了jsCodeLocation,将不能在iOS模拟器上运行。可以使用真机测试。要在发布之前测试热更新功能,可以用adhoc方式发布测试包并进行测试。adhoc发布的包可以用于uploadIpa和生成差异包。
|
||||
|
||||
#### XCode报错 "_BZ2_bzRead", referenced from 等
|
||||
|
||||
在工程target的Build Phases->Link Binary with Libraries中加入libz.tbd、libbz2.1.0.tbd
|
||||
|
||||
## 高级指南
|
||||
|
||||
#### 过期的版本
|
||||
|
||||
你可以删除掉过期很久的版本。在一段时间后,版本会被真正清理。
|
||||
|
||||
如果有用户还处在已经被清理的版本上,当他发起更新的时候,将不能通过版本差异比对进行更新,即只能进行全量更新。
|
||||
|
||||
#### CI的集成
|
||||
|
||||
在开发环境中,每次bundle都会生成一个不同名字的ppk文件,这不利于持续集成(CI)系统的引入。
|
||||
|
||||
要解决这个问题,你可以使用`--output`参数来指定输出ppk文件的名字和路径,便于进行自动发布。
|
||||
|
||||
#### 版本测试与发布
|
||||
|
||||
我们强烈建议您先发布一个测试包,再发布一个除了版本号以外均完全相同的发布包。
|
||||
在每次往发布包发起热更新之前,先往对应的测试包进行更新操作,基本测试通过之后,可以将发布包更新到完全相同的热更新版本之上。
|
||||
如果在测试包中发现了重大问题,你就可以先进行修复,再次更新测试通过后,再将发布包更新至修复后的版本。
|
||||
这样,可以最大程度的避免用户通过热更新获得一个有问题的版本。
|
||||
|
||||
#### 元信息(Meta Info)的使用
|
||||
|
||||
在发布热更新版本时,或者在网页端,你可以编辑版本的元信息。
|
||||
这是一段在检查更新时可以获得的字符串,你可以在其中按你所想的格式保存一些信息。
|
||||
|
||||
举例来说,可能某个版本包含一些重要的更新内容,所以用户会得到一个不同样式的通知。如何使用元信息,完全取决于您的想象力!
|
||||
|
||||
下面会列举一些实战中更有意义的元信息的使用。
|
||||
|
||||
#### Hot-fix
|
||||
|
||||
有时候我们不小心发布了一个有严重问题的版本,所以需要进行一个紧急的修复,
|
||||
此时我们可能希望之前已经更新到有问题版本的用户进行紧急甚至静默进行更新。
|
||||
|
||||
这时候,我们可以在元信息中包含有问题的版本的列表,而在客户端检查更新时,将从元信息里取到的列表与当前版本(currentVersion)比对,
|
||||
如果匹配成功,我们就进行静默更新,否则则按照一般的更新流程提示用户。
|
||||
|
||||
#### 这个热更新服务收费吗?
|
||||
|
||||
目前我们的热更新服务完全免费,但限制每个账号不超过3个应用;每个应用不超过10个活跃的包和100个活跃的热更新版本;每个应用每个月不超过10000次下载。iOS和Android版本记做不同的应用。
|
||||
|
||||
已经移除的应用、包版本、热更新版本不在统计之列,所以你可以移除测试时产生的和已过期版本来更有效的利用空间。
|
||||
|
||||
我们会在将来推出付费的升级版本,针对用户量较大、版本迭代较快的用户提供扩容方案。如果您有急迫的需求,可以[联系我们](https://reactnative.cn/about.html#content)。
|
||||
|
||||
#### 我是否可以搭建自己的热更新服务?
|
||||
|
||||
你可以单独使用本组件的原生部分(不包括js模块)和命令行工具中的`bundle`、`diff`、`diffFromIpa`、`diffFromApk`四个功能。
|
||||
|
||||
这些功能都不会使用我们的热更新服务,也无需注册或登录账号。但你可能要编写自己的js模块来与不同的热更新服务器通讯。
|
||||
|
||||
如果您有兴趣使用我们的成果,搭建私有云服务,可以[联系我们](https://reactnative.cn/about.html#content)。
|
||||
|
228
docs/guide.md
228
docs/guide.md
@@ -1,228 +0,0 @@
|
||||
# 快速入门-准备工作
|
||||
|
||||
首先你应该有一个基于React Native开发的应用,我们把具有package.json的目录叫做你的"应用根目录"。
|
||||
|
||||
如果你还没有初始化应用,请参阅[开始使用React Native](https://reactnative.cn/docs/getting-started.html#content)。
|
||||
|
||||
所以我们也假设你已经拥有了开发React Native应用的一切环境,包括`Node.js`、`npm`、`XCode`、`Android SDK`等等。
|
||||
|
||||
## 安装
|
||||
|
||||
在你的项目根目录下运行以下命令:
|
||||
|
||||
```bash
|
||||
npm i -g react-native-update-cli
|
||||
npm i react-native-update
|
||||
```
|
||||
|
||||
> 如果下载极慢或者显示网络失败,请设置使用淘宝镜像`npx nrm use taobao`
|
||||
|
||||
如果你的RN版本 >= 0.60,请在iOS目录下执行:
|
||||
|
||||
```bash
|
||||
pod install
|
||||
```
|
||||
|
||||
如果你的RN版本 < 0.60,那么还需要[手动link](#一手动link)
|
||||
|
||||
|
||||
<details>
|
||||
<summary>
|
||||
如果你的RN版本比较老(< 0.46),请点击这里的注意事项
|
||||
</summary>
|
||||
|
||||
如果你的RN版本比较老,请按下面表格尝试老一些的版本(但这些版本我们已不再维护,不能保证可以使用):
|
||||
|
||||
| React Native版本 | react-native-update版本 |
|
||||
| ---------------- | ----------------------- |
|
||||
| 0.26及以下 | 1.0.x |
|
||||
| 0.27 - 0.28 | 2.x |
|
||||
| 0.29 - 0.33 | 3.x |
|
||||
| 0.34 - 0.45 | 4.x |
|
||||
|
||||
安装命令示例:
|
||||
```
|
||||
npm i react-native-update@4.x
|
||||
```
|
||||
|
||||
如果RN的版本是0.45及以下,你还必须安装[Android NDK](http://androiddevtools.cn),版本最好选用r10e,并设置环境变量`ANDROID_NDK_HOME`,指向你的NDK根目录(例如`/Users/tdzl2003/Downloads/android-ndk-r10e`)。
|
||||
</details>
|
||||
|
||||
|
||||
请记得一定要重新编译(react-native run-ios或run-android命令编译,或在Xcode/Android Studio中重新编译)。
|
||||
|
||||
|
||||
## 手动link
|
||||
|
||||
如果RN版本 >= 0.60则可以跳过此步骤
|
||||
|
||||
### iOS
|
||||
|
||||
<details>
|
||||
<summary>RN < 0.60且使用CocoaPods(推荐)</summary>
|
||||
|
||||
1. 在ios/Podfile中添加
|
||||
```
|
||||
pod 'react-native-update', path: '../node_modules/react-native-update'
|
||||
```
|
||||
2. 在项目的ios目录下运行`pod install`
|
||||
3. 重新编译
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>RN < 0.60且不使用CocoaPods</summary>
|
||||
|
||||
1. 在XCode中的Project Navigator里,右键点击`Libraries` ➜ `Add Files to [你的工程名]`
|
||||
2. 进入`node_modules` ➜ `react-native-update` ➜ `ios 并选中 `RCTPushy.xcodeproj`
|
||||
3. 在XCode中的project navigator里,选中你的工程,在 `Build Phases` ➜ `Link Binary With Libraries` 中添加 `libRCTPushy.a`
|
||||
4. 继续在`Build Settings`里搜索`Header Search Path`,添加$(SRCROOT)/../node_modules/react-native-update/ios
|
||||
5. 在`Build Phases`添加一个`New Run Script Phase`运行脚本,内容如下
|
||||
```
|
||||
#!/bin/bash
|
||||
set -x
|
||||
DEST="../node_modules/react-native-update/ios/"
|
||||
date +%s > "$DEST/pushy_build_time.txt"
|
||||
```
|
||||
编译的时候就会在`../node_modules/react-native-update/ios/`文件夹下面生成一个`pushy_build_time.txt`文件。
|
||||
然后在`Copy Bundle Resources`里把生成的`pushy_build_time.txt`文件添加进去。
|
||||
|
||||
6. 重新编译
|
||||
|
||||
</details>
|
||||
|
||||
### Android
|
||||
|
||||
|
||||
<details>
|
||||
<summary>RN < 0.60</summary>
|
||||
1. 在`android/settings.gradle`中添加如下代码:
|
||||
```
|
||||
include ':react-native-update'
|
||||
project(':react-native-update').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-update/android')
|
||||
```
|
||||
|
||||
2. 在`android/app/build.gradle`的 dependencies 部分增加如下代码:
|
||||
```
|
||||
implementation project(':react-native-update')
|
||||
```
|
||||
|
||||
3. 打开`android/app/src/main/java/[...]/MainApplication.java`,
|
||||
- 在文件开头增加 `import cn.reactnative.modules.update.UpdatePackage;`
|
||||
- 在`getPackages()` 方法中增加 `new UpdatePackage()`(注意上一行可能要增加一个逗号)
|
||||
</details>
|
||||
|
||||
## 配置Bundle URL
|
||||
|
||||
注意此步骤无论任何版本,目前都需要手动配置。
|
||||
|
||||
### iOS
|
||||
|
||||
1. (RN >= 0.60或者使用CocoaPods集成此步可跳过)在工程target的Build Phases->Link Binary with Libraries中加入`libz.tbd`、`libbz2.1.0.tbd`
|
||||
|
||||
2. 在你的AppDelegate.m文件中增加如下代码:
|
||||
|
||||
```objective-c
|
||||
// ... 其它代码
|
||||
|
||||
#import "RCTPushy.h"
|
||||
|
||||
// 如果RN版本 >= 0.59,修改sourceURLForBridge
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||
#else
|
||||
// 非DEBUG情况下替换为热更新bundle
|
||||
return [RCTPushy bundleURL];
|
||||
#endif
|
||||
}
|
||||
|
||||
// 如果RN版本 < 0.59,修改didFinishLaunchingWithOptions
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
#if DEBUG
|
||||
// 原来的jsCodeLocation保留在这里
|
||||
jsCodeLocation = ..........
|
||||
#else
|
||||
// 非DEBUG情况下替换为热更新bundle
|
||||
jsCodeLocation = [RCTPushy bundleURL];
|
||||
#endif
|
||||
// ... 其它代码
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Android
|
||||
|
||||
在MainApplication中增加如下代码:
|
||||
|
||||
```java
|
||||
// ... 其它代码
|
||||
|
||||
// 请注意不要少了这句import
|
||||
import cn.reactnative.modules.update.UpdateContext;
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
|
||||
@Override
|
||||
protected String getJSBundleFile() {
|
||||
return UpdateContext.getBundleUrl(MainApplication.this);
|
||||
}
|
||||
// ... 其它代码
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 登录与创建应用
|
||||
|
||||
首先请在<https://update.reactnative.cn>注册帐号,然后在你的项目根目录下运行以下命令:
|
||||
|
||||
```bash
|
||||
$ pushy login
|
||||
email: <输入你的注册邮箱>
|
||||
password: <输入你的密码>
|
||||
```
|
||||
|
||||
这会在项目文件夹下创建一个`.update`文件,注意不要把这个文件上传到Git等CVS系统上。你可以在`.gitignore`末尾增加一行`.update`来忽略这个文件。
|
||||
|
||||
登录之后可以创建应用。注意iOS平台和安卓平台需要分别创建:
|
||||
|
||||
```bash
|
||||
$ pushy createApp --platform ios
|
||||
App Name: <输入应用名字>
|
||||
$ pushy createApp --platform android
|
||||
App Name: <输入应用名字>
|
||||
```
|
||||
|
||||
> 两次输入的名字可以相同,这没有关系。
|
||||
|
||||
如果你已经在网页端或者其它地方创建过应用,也可以直接选择应用:
|
||||
|
||||
```bash
|
||||
$ pushy selectApp --platform ios
|
||||
1) 鱼多多(ios)
|
||||
2) 招财旺(ios)
|
||||
|
||||
Total 2 ios apps
|
||||
Enter appId: <输入应用前面的编号>
|
||||
```
|
||||
|
||||
选择或者创建过应用后,你将可以在文件夹下看到`update.json`文件,其内容类似如下形式:
|
||||
|
||||
```bash
|
||||
{
|
||||
"ios": {
|
||||
"appId": 1,
|
||||
"appKey": "<一串随机字符串>"
|
||||
},
|
||||
"android": {
|
||||
"appId": 2,
|
||||
"appKey": "<一串随机字符串>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
你可以安全的把`update.json`上传到Git等CVS系统上,与你的团队共享这个文件,它不包含任何敏感信息。当然,他们在使用任何功能之前,都必须首先输入`pushy login`进行登录。
|
||||
|
||||
至此应用的创建/选择就已经成功了。下一步,你需要给代码添加相应的功能,请参阅[添加热更新功能](guide2.md)
|
177
docs/guide2.md
177
docs/guide2.md
@@ -1,177 +0,0 @@
|
||||
# 快速入门-添加热更新功能
|
||||
|
||||
## 获取appKey
|
||||
|
||||
检查更新时必须提供你的`appKey`,这个值保存在`update.json`中,并且根据平台不同而不同。你可以用如下的代码获取:
|
||||
|
||||
```javascript
|
||||
import {
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
|
||||
import _updateConfig from './update.json';
|
||||
const {appKey} = _updateConfig[Platform.OS];
|
||||
```
|
||||
|
||||
如果你不使用pushy命令行,你也可以从网页端查看到两个应用appKey,并根据平台的不同来选择。
|
||||
|
||||
## 检查更新、下载更新
|
||||
|
||||
异步函数checkUpdate可以检查当前版本是否需要更新:
|
||||
|
||||
```javascript
|
||||
const info = await checkUpdate(appKey)
|
||||
```
|
||||
|
||||
返回的info有三种情况:
|
||||
|
||||
1. `{expired: true}`:该应用包(原生部分)已过期,需要前往应用市场下载新的版本。
|
||||
|
||||
2. `{upToDate: true}`:当前已经更新到最新,无需进行更新。
|
||||
|
||||
3. `{update: true}`:当前有新版本可以更新。info的`name`、`description`字段可
|
||||
以用于提示用户,而`metaInfo`字段则可以根据你的需求自定义其它属性(如是否静默更新、
|
||||
是否强制更新等等)。另外还有几个字段,包含了完整更新包或补丁包的下载地址,
|
||||
react-native-update会首先尝试耗费流量更少的更新方式。将info对象传递给downloadUpdate作为参数即可。
|
||||
|
||||
## 切换版本
|
||||
|
||||
downloadUpdate的返回值是一个hash字符串,它是当前版本的唯一标识。
|
||||
|
||||
你可以使用`switchVersion`函数立即切换版本(此时应用会立即重新加载),或者选择调用
|
||||
`switchVersionLater`,让应用在下一次启动的时候再加载新的版本。
|
||||
|
||||
## 首次启动、回滚
|
||||
|
||||
在每次更新完毕后的首次启动时,`isFirstTime`常量会为`true`。
|
||||
你必须在应用退出前合适的任何时机,调用`markSuccess`,否则应用下一次启动的时候将会进行回滚操作。
|
||||
这一机制称作“反触发”,这样当你应用启动初期即遭遇问题的时候,也能在下一次启动时恢复运作。
|
||||
|
||||
你可以通过`isFirstTime`来获知这是当前版本的首次启动,也可以通过`isRolledBack`来获知应用刚刚经历了一次回滚操作。
|
||||
你可以在此时给予用户合理的提示。
|
||||
|
||||
## 完整的示例
|
||||
|
||||
```javascript
|
||||
import React, {
|
||||
Component,
|
||||
} from 'react';
|
||||
|
||||
import {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Platform,
|
||||
Text,
|
||||
View,
|
||||
Alert,
|
||||
TouchableOpacity,
|
||||
Linking,
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
isFirstTime,
|
||||
isRolledBack,
|
||||
packageVersion,
|
||||
currentVersion,
|
||||
checkUpdate,
|
||||
downloadUpdate,
|
||||
switchVersion,
|
||||
switchVersionLater,
|
||||
markSuccess,
|
||||
} from 'react-native-update';
|
||||
|
||||
import _updateConfig from './update.json';
|
||||
const {appKey} = _updateConfig[Platform.OS];
|
||||
|
||||
class MyProject extends Component {
|
||||
componentDidMount(){
|
||||
if (isFirstTime) {
|
||||
Alert.alert('提示', '这是当前版本第一次启动,是否要模拟启动失败?失败将回滚到上一版本', [
|
||||
{text: '是', onPress: ()=>{throw new Error('模拟启动失败,请重启应用')}},
|
||||
{text: '否', onPress: ()=>{markSuccess()}},
|
||||
]);
|
||||
} else if (isRolledBack) {
|
||||
Alert.alert('提示', '刚刚更新失败了,版本被回滚.');
|
||||
}
|
||||
}
|
||||
doUpdate = async (info) => {
|
||||
try {
|
||||
const hash = await downloadUpdate(info);
|
||||
Alert.alert('提示', '下载完毕,是否重启应用?', [
|
||||
{text: '是', onPress: ()=>{switchVersion(hash);}},
|
||||
{text: '否',},
|
||||
{text: '下次启动时', onPress: ()=>{switchVersionLater(hash);}},
|
||||
]);
|
||||
} catch(err) {
|
||||
Alert.alert('提示', '更新失败.');
|
||||
}
|
||||
};
|
||||
checkUpdate = async () => {
|
||||
if (__DEV__) {
|
||||
// 开发模式不支持热更新,跳过检查
|
||||
return;
|
||||
}
|
||||
let info;
|
||||
try {
|
||||
info = await checkUpdate(appKey);
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
return;
|
||||
}
|
||||
if (info.expired) {
|
||||
Alert.alert('提示', '您的应用版本已更新,请前往应用商店下载新的版本', [
|
||||
{text: '确定', onPress: ()=>{info.downloadUrl && Linking.openURL(info.downloadUrl)}},
|
||||
]);
|
||||
} else if (info.upToDate) {
|
||||
Alert.alert('提示', '您的应用版本已是最新.');
|
||||
} else {
|
||||
Alert.alert('提示', '检查到新的版本'+info.name+',是否下载?\n'+ info.description, [
|
||||
{text: '是', onPress: ()=>{this.doUpdate(info)}},
|
||||
{text: '否',},
|
||||
]);
|
||||
}
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text style={styles.welcome}>
|
||||
欢迎使用热更新服务
|
||||
</Text>
|
||||
<Text style={styles.instructions}>
|
||||
这是版本一 {'\n'}
|
||||
当前包版本号: {packageVersion}{'\n'}
|
||||
当前版本Hash: {currentVersion||'(空)'}{'\n'}
|
||||
</Text>
|
||||
<TouchableOpacity onPress={this.checkUpdate}>
|
||||
<Text style={styles.instructions}>
|
||||
点击这里检查更新
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5FCFF',
|
||||
},
|
||||
welcome: {
|
||||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
margin: 10,
|
||||
},
|
||||
instructions: {
|
||||
textAlign: 'center',
|
||||
color: '#333333',
|
||||
marginBottom: 5,
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('MyProject', () => MyProject);
|
||||
```
|
||||
|
||||
现在,你的应用已经可以通过update服务检查版本并进行更新了。下一步,你可以开始尝试发布应用包和版本,请参阅[发布应用](guide3.md)
|
@@ -1,80 +0,0 @@
|
||||
# 快速入门-发布应用
|
||||
|
||||
现在你的应用已经具备了检测更新的功能,下面我们来尝试发布并更新它。
|
||||
|
||||
> **注意**,从update上传发布版本到发布版本正式上线期间,不要修改任何脚本和资源,这会影响update
|
||||
获取本地代码,从而导致版本不能更新。如果在发布之前修改了脚本或资源,请在网页端删除之前上传的版本并重新上传。
|
||||
|
||||
## 发布iOS应用
|
||||
|
||||
首先参考[文档-在设备上运行](https://reactnative.cn/docs/running-on-device-ios.html#content),
|
||||
确定你正在使用离线包。然后点击菜单。
|
||||
|
||||
按照正常的发布流程打包`.ipa`文件(Xcode中运行设备选真机或Generic iOS Device,然后菜单中选择Product-Archive),然后运行如下命令
|
||||
|
||||
```bash
|
||||
$ pushy uploadIpa <your-package.ipa>
|
||||
```
|
||||
|
||||
即可上传ipa以供后续版本比对之用。
|
||||
|
||||
随后你可以选择往AppStore发布这个版本,也可以先通过Test flight等方法进行测试。
|
||||
|
||||
## 发布安卓应用
|
||||
|
||||
首先参考[文档-生成已签名的APK](https://reactnative.cn/docs/signed-apk-android.html#content)设置签名,
|
||||
然后在android文件夹下运行`./gradlew assembleRelease`或`./gradlew aR`,你就可以在`android/app/build/outputs/apk/release/app-release.apk`中找到你的应用包。
|
||||
|
||||
然后运行如下命令
|
||||
|
||||
```bash
|
||||
$ pushy uploadApk android/app/build/outputs/apk/release/app-release.apk
|
||||
```
|
||||
|
||||
即可上传apk以供后续版本比对之用。
|
||||
|
||||
随后你可以选择往应用市场发布这个版本,也可以先往设备上直接安装这个apk文件以进行测试。
|
||||
|
||||
## 发布新的热更新版本
|
||||
|
||||
你可以尝试修改一行代码(譬如将版本一修改为版本二),然后生成新的热更新版本。
|
||||
|
||||
```bash
|
||||
$ pushy bundle --platform <ios|android>
|
||||
Bundling with React Native version: 0.22.2
|
||||
<各种进度输出>
|
||||
Bundled saved to: build/output/android.1459850548545.ppk
|
||||
Would you like to publish it?(Y/N)
|
||||
```
|
||||
|
||||
如果想要立即发布,此时输入Y。当然,你也可以在将来使用`pushy publish --platform <ios|android> <ppkFile>`来发布版本。
|
||||
|
||||
```
|
||||
Uploading [========================================================] 100% 0.0s
|
||||
Enter version name: <输入版本名字,如1.0.0-rc>
|
||||
Enter description: <输入版本描述>
|
||||
Enter meta info: {"ok":1}
|
||||
Ok.
|
||||
Would you like to bind packages to this version?(Y/N)
|
||||
```
|
||||
|
||||
此时版本已经提交到update服务,但用户暂时看不到此更新,你需要先将特定的包版本绑定到此热更新版本上。
|
||||
|
||||
此时输入Y立即绑定,你也可以在将来使用`pushy update --platform <ios|android>`来使得对应包版本的用户更新。
|
||||
除此以外,你还可以在网页端操作,简单的将对应的包版本拖到此版本下即可。
|
||||
|
||||
```
|
||||
Offset 0
|
||||
1) FvXnROJ1 1.0.1 (no package)
|
||||
2) FiWYm9lB 1.0 [1.0]
|
||||
Enter versionId or page Up/page Down/Begin(U/D/B) <输入序号,U/D翻页,B回到开始,序号就是上面列表中)前面的数字>
|
||||
|
||||
1) 1.0(normal) - 3 FiWYm9lB (未命名)
|
||||
|
||||
Total 1 packages.
|
||||
Enter packageId: <输入包版本序号,序号就是上面列表中)前面的数字>
|
||||
```
|
||||
|
||||
版本绑定完毕后,客户端就应当可以检查到更新并进行更新了。
|
||||
|
||||
恭喜你,至此为止,你已经完成了植入代码热更新的全部工作。接下来,你可以查阅[常见问题与高级指南](faq_advance.md)了解更多深入的知识,尤其是在实际项目中的运用技巧。
|
@@ -1,25 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>react-native-update - react-native hot update</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="description" content="react-native hot update">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/vue.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script>
|
||||
window.$docsify = {
|
||||
name: 'react-native-update',
|
||||
repo: 'https://github.com/reactnativecn/react-native-pushy',
|
||||
formatUpdated: '{MM}/{DD} {HH}:{mm}',
|
||||
loadSidebar: true,
|
||||
subMaxLevel: 2,
|
||||
auto2top: true
|
||||
}
|
||||
</script>
|
||||
<script src="//cdn.jsdelivr.net/npm/docsify/lib/docsify.min.js"></script>
|
||||
</body>
|
||||
</html>
|
1
domains.json
Normal file
1
domains.json
Normal file
@@ -0,0 +1 @@
|
||||
["update.react-native.cn", "update.reactnative.cn"]
|
1
endpoints.json
Normal file
1
endpoints.json
Normal file
@@ -0,0 +1 @@
|
||||
["https://update.react-native.cn/api", "https://update.reactnative.cn/api"]
|
@@ -7,6 +7,12 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
249F2F50261C577300A1E60E /* HDiffPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F4E261C577300A1E60E /* HDiffPatch.m */; };
|
||||
249F2F55261C584900A1E60E /* hpatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F54261C584900A1E60E /* hpatch.c */; };
|
||||
249F2F59261C586900A1E60E /* file_for_patch.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F58261C586900A1E60E /* file_for_patch.c */; };
|
||||
249F2F5E261C589D00A1E60E /* patch.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F5C261C589D00A1E60E /* patch.c */; };
|
||||
249F2F64261C58C700A1E60E /* Lzma2Dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F60261C58C700A1E60E /* Lzma2Dec.c */; };
|
||||
249F2F65261C58C700A1E60E /* LzmaDec.c in Sources */ = {isa = PBXBuildFile; fileRef = 249F2F62261C58C700A1E60E /* LzmaDec.c */; };
|
||||
91C5F0031C76ECA90037E727 /* RCTPushy.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 91C5F0021C76ECA90037E727 /* RCTPushy.h */; };
|
||||
91C5F0051C76ECA90037E727 /* RCTPushy.m in Sources */ = {isa = PBXBuildFile; fileRef = 91C5F0041C76ECA90037E727 /* RCTPushy.m */; };
|
||||
9F1BCB1D1CAE5937000EF2CB /* RCTPushyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F1BCB1C1CAE5937000EF2CB /* RCTPushyManager.m */; };
|
||||
@@ -43,6 +49,19 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
249F2F4E261C577300A1E60E /* HDiffPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HDiffPatch.m; sourceTree = "<group>"; };
|
||||
249F2F4F261C577300A1E60E /* HDiffPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDiffPatch.h; sourceTree = "<group>"; };
|
||||
249F2F53261C584900A1E60E /* hpatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hpatch.h; path = ../../../android/jni/hpatch.h; sourceTree = "<group>"; };
|
||||
249F2F54261C584900A1E60E /* hpatch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hpatch.c; path = ../../../android/jni/hpatch.c; sourceTree = "<group>"; };
|
||||
249F2F57261C586900A1E60E /* file_for_patch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = file_for_patch.h; path = ../../../android/jni/HDiffPatch/file_for_patch.h; sourceTree = "<group>"; };
|
||||
249F2F58261C586900A1E60E /* file_for_patch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = file_for_patch.c; path = ../../../android/jni/HDiffPatch/file_for_patch.c; sourceTree = "<group>"; };
|
||||
249F2F5B261C589C00A1E60E /* patch_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = patch_types.h; path = ../../../android/jni/HDiffPatch/libHDiffPatch/HPatch/patch_types.h; sourceTree = "<group>"; };
|
||||
249F2F5C261C589D00A1E60E /* patch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = patch.c; path = ../../../android/jni/HDiffPatch/libHDiffPatch/HPatch/patch.c; sourceTree = "<group>"; };
|
||||
249F2F5D261C589D00A1E60E /* patch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = patch.h; path = ../../../android/jni/HDiffPatch/libHDiffPatch/HPatch/patch.h; sourceTree = "<group>"; };
|
||||
249F2F60261C58C700A1E60E /* Lzma2Dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Lzma2Dec.c; path = ../../../android/jni/lzma/C/Lzma2Dec.c; sourceTree = "<group>"; };
|
||||
249F2F61261C58C700A1E60E /* Lzma2Dec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Lzma2Dec.h; path = ../../../android/jni/lzma/C/Lzma2Dec.h; sourceTree = "<group>"; };
|
||||
249F2F62261C58C700A1E60E /* LzmaDec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = LzmaDec.c; path = ../../../android/jni/lzma/C/LzmaDec.c; sourceTree = "<group>"; };
|
||||
249F2F63261C58C700A1E60E /* LzmaDec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LzmaDec.h; path = ../../../android/jni/lzma/C/LzmaDec.h; sourceTree = "<group>"; };
|
||||
91C5EFFF1C76ECA90037E727 /* libRCTPushy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTPushy.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
91C5F0021C76ECA90037E727 /* RCTPushy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTPushy.h; sourceTree = "<group>"; };
|
||||
91C5F0041C76ECA90037E727 /* RCTPushy.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTPushy.m; sourceTree = "<group>"; };
|
||||
@@ -102,6 +121,34 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
249F2F4D261C56E100A1E60E /* HDiffPatch */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
249F2F52261C581200A1E60E /* hpatch */,
|
||||
249F2F4F261C577300A1E60E /* HDiffPatch.h */,
|
||||
249F2F4E261C577300A1E60E /* HDiffPatch.m */,
|
||||
);
|
||||
path = HDiffPatch;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
249F2F52261C581200A1E60E /* hpatch */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
249F2F60261C58C700A1E60E /* Lzma2Dec.c */,
|
||||
249F2F61261C58C700A1E60E /* Lzma2Dec.h */,
|
||||
249F2F62261C58C700A1E60E /* LzmaDec.c */,
|
||||
249F2F63261C58C700A1E60E /* LzmaDec.h */,
|
||||
249F2F5B261C589C00A1E60E /* patch_types.h */,
|
||||
249F2F5C261C589D00A1E60E /* patch.c */,
|
||||
249F2F5D261C589D00A1E60E /* patch.h */,
|
||||
249F2F58261C586900A1E60E /* file_for_patch.c */,
|
||||
249F2F57261C586900A1E60E /* file_for_patch.h */,
|
||||
249F2F54261C584900A1E60E /* hpatch.c */,
|
||||
249F2F53261C584900A1E60E /* hpatch.h */,
|
||||
);
|
||||
name = hpatch;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
91C5EFF61C76ECA90037E727 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -121,6 +168,7 @@
|
||||
91C5F0011C76ECA90037E727 /* RCTPushy */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
249F2F4D261C56E100A1E60E /* HDiffPatch */,
|
||||
9F1BCB381CAF6B3E000EF2CB /* BSDiff */,
|
||||
9F394D571C7C25DC00C794C0 /* SSZipArchive */,
|
||||
91C5F0021C76ECA90037E727 /* RCTPushy.h */,
|
||||
@@ -272,19 +320,25 @@
|
||||
9F394D871C7C25DC00C794C0 /* mztools.c in Sources */,
|
||||
9F394D821C7C25DC00C794C0 /* hmac.c in Sources */,
|
||||
9F394D881C7C25DC00C794C0 /* unzip.c in Sources */,
|
||||
249F2F65261C58C700A1E60E /* LzmaDec.c in Sources */,
|
||||
9F1BCB1D1CAE5937000EF2CB /* RCTPushyManager.m in Sources */,
|
||||
249F2F5E261C589D00A1E60E /* patch.c in Sources */,
|
||||
9F1BCB4F1CAF6B68000EF2CB /* BSDiff.m in Sources */,
|
||||
9F394D7E1C7C25DC00C794C0 /* aeskey.c in Sources */,
|
||||
9F394D7F1C7C25DC00C794C0 /* aestab.c in Sources */,
|
||||
9F394D7D1C7C25DC00C794C0 /* aescrypt.c in Sources */,
|
||||
9F394D801C7C25DC00C794C0 /* entropy.c in Sources */,
|
||||
9F292F7D1C7C44290095945D /* RCTPushyDownloader.m in Sources */,
|
||||
249F2F64261C58C700A1E60E /* Lzma2Dec.c in Sources */,
|
||||
249F2F55261C584900A1E60E /* hpatch.c in Sources */,
|
||||
9F394D831C7C25DC00C794C0 /* prng.c in Sources */,
|
||||
9F394D861C7C25DC00C794C0 /* ioapi.c in Sources */,
|
||||
9F1BCB461CAF6B3E000EF2CB /* bspatch.c in Sources */,
|
||||
9F394D8A1C7C25DC00C794C0 /* SSZipArchive.m in Sources */,
|
||||
249F2F50261C577300A1E60E /* HDiffPatch.m in Sources */,
|
||||
9F394D891C7C25DC00C794C0 /* zip.c in Sources */,
|
||||
9F394D841C7C25DC00C794C0 /* pwd2key.c in Sources */,
|
||||
249F2F59261C586900A1E60E /* file_for_patch.c in Sources */,
|
||||
91C5F0051C76ECA90037E727 /* RCTPushy.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// BSDiff.h
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by lvbingru on 16/4/2.
|
||||
// Copyright © 2016年 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface BSDiff : NSObject
|
||||
|
||||
+ (BOOL)bsdiffPatch:(NSString *)path
|
||||
origin:(NSString *)origin
|
||||
toDestination:(NSString *)destination;
|
||||
@end
|
@@ -1,194 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2003-2005 Colin Percival
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "bspatch.h"
|
||||
#include <bzlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static int64_t offtin(uint8_t *buf)
|
||||
{
|
||||
int64_t y;
|
||||
|
||||
y=buf[7]&0x7F;
|
||||
y=y*256;y+=buf[6];
|
||||
y=y*256;y+=buf[5];
|
||||
y=y*256;y+=buf[4];
|
||||
y=y*256;y+=buf[3];
|
||||
y=y*256;y+=buf[2];
|
||||
y=y*256;y+=buf[1];
|
||||
y=y*256;y+=buf[0];
|
||||
|
||||
if(buf[7]&0x80) y=-y;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream)
|
||||
{
|
||||
uint8_t buf[8];
|
||||
int64_t oldpos,newpos;
|
||||
int64_t ctrl[3];
|
||||
int64_t i;
|
||||
|
||||
oldpos=0;newpos=0;
|
||||
while(newpos<newsize) {
|
||||
/* Read control data */
|
||||
for(i=0;i<=2;i++) {
|
||||
if (stream->read(stream, buf, 8))
|
||||
return -1;
|
||||
ctrl[i]=offtin(buf);
|
||||
};
|
||||
|
||||
/* Sanity-check */
|
||||
if(newpos+ctrl[0]>newsize)
|
||||
return -1;
|
||||
|
||||
/* Read diff string */
|
||||
if (stream->read(stream, new + newpos, ctrl[0]))
|
||||
return -1;
|
||||
|
||||
/* Add old data to diff string */
|
||||
for(i=0;i<ctrl[0];i++)
|
||||
if((oldpos+i>=0) && (oldpos+i<oldsize))
|
||||
new[newpos+i]+=old[oldpos+i];
|
||||
|
||||
/* Adjust pointers */
|
||||
newpos+=ctrl[0];
|
||||
oldpos+=ctrl[0];
|
||||
|
||||
/* Sanity-check */
|
||||
if(newpos+ctrl[1]>newsize)
|
||||
return -1;
|
||||
|
||||
/* Read extra string */
|
||||
if (stream->read(stream, new + newpos, ctrl[1]))
|
||||
return -1;
|
||||
|
||||
/* Adjust pointers */
|
||||
newpos+=ctrl[1];
|
||||
oldpos+=ctrl[2];
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length)
|
||||
{
|
||||
int n;
|
||||
int bz2err;
|
||||
BZFILE* bz2;
|
||||
|
||||
bz2 = (BZFILE*)stream->opaque;
|
||||
n = BZ2_bzRead(&bz2err, bz2, buffer, length);
|
||||
if (n != length)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int beginPatch(const char* oldfile, const char* newfile, const char* patchfile)
|
||||
{
|
||||
FILE * f;
|
||||
int fd;
|
||||
int bz2err;
|
||||
uint8_t header[32];
|
||||
uint8_t *old, *new;
|
||||
int64_t oldsize, newsize;
|
||||
BZFILE* bz2;
|
||||
struct bspatch_stream stream;
|
||||
|
||||
// if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
|
||||
|
||||
/* Open patch file */
|
||||
if ((f = fopen(patchfile, "r")) == NULL) {
|
||||
// err(1, "fopen(%s)", patchfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read header */
|
||||
if (fread(header, 1, 32, f) != 32) {
|
||||
if (feof(f)) {
|
||||
// errx(1, "Corrupt patch\n");
|
||||
}
|
||||
// err(1, "fread(%s)", patchfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check for appropriate magic */
|
||||
if (memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0) {
|
||||
// errx(1, "Corrupt patch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read lengths from header */
|
||||
newsize=offtin(header+16);
|
||||
if(newsize<0) {
|
||||
// errx(1,"Corrupt patch\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Close patch file and re-open it via libbzip2 at the right places */
|
||||
if(((fd=open(oldfile,O_RDONLY,0))<0) ||
|
||||
((oldsize=lseek(fd,0,SEEK_END))==-1) ||
|
||||
((old=malloc(oldsize+1))==NULL) ||
|
||||
(lseek(fd,0,SEEK_SET)!=0) ||
|
||||
(read(fd,old,oldsize)!=oldsize) ||
|
||||
(close(fd)==-1)) err(1,"%s",oldfile);
|
||||
if((new=malloc(newsize+1))==NULL) err(1,NULL);
|
||||
|
||||
if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 1, NULL, 0))) {
|
||||
// errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream.read = bz2_read;
|
||||
stream.opaque = bz2;
|
||||
if (bspatch(old, oldsize, new, newsize, &stream)) {
|
||||
// errx(1, "bspatch");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Clean up the bzip2 reads */
|
||||
BZ2_bzReadClose(&bz2err, bz2);
|
||||
fclose(f);
|
||||
|
||||
/* Write the new file */
|
||||
if(((fd=open(newfile,O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
|
||||
(write(fd,new,newsize)!=newsize) || (close(fd)==-1)) {
|
||||
err(1,"%s",newfile);
|
||||
return -1;
|
||||
}
|
||||
free(new);
|
||||
free(old);
|
||||
return 0;
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
/*-
|
||||
* Copyright 2003-2005 Colin Percival
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef BSPATCH_H
|
||||
# define BSPATCH_H
|
||||
|
||||
# include <stdint.h>
|
||||
|
||||
struct bspatch_stream
|
||||
{
|
||||
void* opaque;
|
||||
int (*read)(const struct bspatch_stream* stream, void* buffer, int length);
|
||||
};
|
||||
|
||||
int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* newBuf, int64_t newsize, struct bspatch_stream* stream);
|
||||
int beginPatch(const char* oldfile, const char* newfile, const char* patchfile);
|
||||
|
||||
#endif
|
16
ios/RCTPushy/HDiffPatch/HDiffPatch.h
Normal file
16
ios/RCTPushy/HDiffPatch/HDiffPatch.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// HDiffPatch.h
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by HouSisong, All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface HDiffPatch : NSObject
|
||||
|
||||
+ (BOOL)hdiffPatch:(NSString *)path
|
||||
origin:(NSString *)origin
|
||||
toDestination:(NSString *)destination;
|
||||
|
||||
@end
|
@@ -1,20 +1,18 @@
|
||||
//
|
||||
// BSDiff.m
|
||||
// HDiffPatch.m
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by lvbingru on 16/4/2.
|
||||
// Copyright © 2016年 erica. All rights reserved.
|
||||
// Created by HouSisong, All rights reserved.
|
||||
//
|
||||
|
||||
#import "BSDiff.h"
|
||||
#include "bspatch.h"
|
||||
#import "HDiffPatch.h"
|
||||
#include "../../../android/jni/hpatch.h"
|
||||
|
||||
@implementation HDiffPatch
|
||||
|
||||
@implementation BSDiff
|
||||
|
||||
+ (BOOL)bsdiffPatch:(NSString *)patch
|
||||
+ (BOOL)hdiffPatch:(NSString *)patch
|
||||
origin:(NSString *)origin
|
||||
toDestination:(NSString *)destination
|
||||
toDestination:(NSString *)destination
|
||||
{
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:patch]) {
|
||||
return NO;
|
||||
@@ -27,7 +25,7 @@
|
||||
[[NSFileManager defaultManager] removeItemAtPath:destination error:nil];
|
||||
}
|
||||
|
||||
int err = beginPatch([origin UTF8String], [destination UTF8String], [patch UTF8String]);
|
||||
int err = hpatch_by_file([origin UTF8String], [destination UTF8String], [patch UTF8String]);
|
||||
if (err) {
|
||||
return NO;
|
||||
}
|
@@ -1,18 +1,8 @@
|
||||
//
|
||||
// RCTPushy.h
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by LvBingru on 2/19/16.
|
||||
// Copyright © 2016 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#if __has_include(<React/RCTBridge.h>)
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#else
|
||||
#import "RCTBridgeModule.h"
|
||||
#endif
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface RCTPushy : NSObject<RCTBridgeModule>
|
||||
|
||||
@interface RCTPushy : RCTEventEmitter<RCTBridgeModule>
|
||||
|
||||
+ (NSURL *)bundleURL;
|
||||
|
||||
|
@@ -1,32 +1,21 @@
|
||||
//
|
||||
// RCTPushy.m
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by LvBingru on 2/19/16.
|
||||
// Copyright © 2016 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RCTPushy.h"
|
||||
#import "RCTPushyDownloader.h"
|
||||
#import "RCTPushyManager.h"
|
||||
|
||||
#if __has_include(<React/RCTBridge.h>)
|
||||
#import "React/RCTEventDispatcher.h"
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTLog.h>
|
||||
#else
|
||||
#import "RCTEventDispatcher.h"
|
||||
#import "RCTConvert.h"
|
||||
#import "RCTLog.h"
|
||||
#endif
|
||||
// #import <React/RCTReloadCommand.h>
|
||||
|
||||
//
|
||||
static NSString *const keyPushyInfo = @"REACTNATIVECN_PUSHY_INFO_KEY";
|
||||
static NSString *const paramPackageVersion = @"packageVersion";
|
||||
static NSString *const paramLastVersion = @"lastVersion";
|
||||
static NSString *const paramCurrentVersion = @"currentVersion";
|
||||
static NSString *const paramIsFirstTime = @"isFirstTime";
|
||||
static NSString *const paramIsFirstLoadOk = @"isFirstLoadOK";
|
||||
static NSString *const keyBlockUpdate = @"REACTNATIVECN_PUSHY_BLOCKUPDATE";
|
||||
static NSString *const keyUuid = @"REACTNATIVECN_PUSHY_UUID";
|
||||
static NSString *const keyHashInfo = @"REACTNATIVECN_PUSHY_HASH_";
|
||||
static NSString *const keyFirstLoadMarked = @"REACTNATIVECN_PUSHY_FIRSTLOADMARKED_KEY";
|
||||
static NSString *const keyRolledBackMarked = @"REACTNATIVECN_PUSHY_ROLLEDBACKMARKED_KEY";
|
||||
static NSString *const KeyPackageUpdatedMarked = @"REACTNATIVECN_PUSHY_ISPACKAGEUPDATEDMARKED_KEY";
|
||||
@@ -42,13 +31,13 @@ static NSString * const BUNDLE_PATCH_NAME = @"index.bundlejs.patch";
|
||||
|
||||
// error def
|
||||
static NSString * const ERROR_OPTIONS = @"options error";
|
||||
static NSString * const ERROR_BSDIFF = @"bsdiff error";
|
||||
static NSString * const ERROR_HDIFFPATCH = @"hdiffpatch error";
|
||||
static NSString * const ERROR_FILE_OPERATION = @"file operation error";
|
||||
|
||||
// event def
|
||||
static NSString * const EVENT_PROGRESS_DOWNLOAD = @"RCTPushyDownloadProgress";
|
||||
static NSString * const EVENT_PROGRESS_UNZIP = @"RCTPushyUnzipProgress";
|
||||
static NSString * const PARAM_PROGRESS_HASHNAME = @"hashname";
|
||||
// static NSString * const EVENT_PROGRESS_UNZIP = @"RCTPushyUnzipProgress";
|
||||
static NSString * const PARAM_PROGRESS_HASH = @"hash";
|
||||
static NSString * const PARAM_PROGRESS_RECEIVED = @"received";
|
||||
static NSString * const PARAM_PROGRESS_TOTAL = @"total";
|
||||
|
||||
@@ -57,15 +46,16 @@ typedef NS_ENUM(NSInteger, PushyType) {
|
||||
PushyTypeFullDownload = 1,
|
||||
PushyTypePatchFromPackage = 2,
|
||||
PushyTypePatchFromPpk = 3,
|
||||
//TASK_TYPE_PLAIN_DOWNLOAD=4?
|
||||
};
|
||||
|
||||
static BOOL ignoreRollback = false;
|
||||
|
||||
@implementation RCTPushy {
|
||||
RCTPushyManager *_fileManager;
|
||||
bool hasListeners;
|
||||
}
|
||||
|
||||
@synthesize bridge = _bridge;
|
||||
@synthesize methodQueue = _methodQueue;
|
||||
|
||||
RCT_EXPORT_MODULE(RCTPushy);
|
||||
@@ -88,31 +78,14 @@ RCT_EXPORT_MODULE(RCTPushy);
|
||||
}
|
||||
else {
|
||||
NSString *curVersion = pushyInfo[paramCurrentVersion];
|
||||
NSString *lastVersion = pushyInfo[paramLastVersion];
|
||||
|
||||
BOOL isFirstTime = [pushyInfo[paramIsFirstTime] boolValue];
|
||||
BOOL isFirstLoadOK = [pushyInfo[paramIsFirstLoadOk] boolValue];
|
||||
|
||||
NSString *loadVersioin = curVersion;
|
||||
BOOL needRollback = (!ignoreRollback && isFirstTime == NO && isFirstLoadOK == NO) || loadVersioin.length<=0;
|
||||
NSString *loadVersion = curVersion;
|
||||
BOOL needRollback = (!ignoreRollback && isFirstTime == NO && isFirstLoadOK == NO) || loadVersion.length<=0;
|
||||
if (needRollback) {
|
||||
loadVersioin = lastVersion;
|
||||
|
||||
if (lastVersion.length) {
|
||||
// roll back to last version
|
||||
[defaults setObject:@{paramCurrentVersion:lastVersion,
|
||||
paramIsFirstTime:@(NO),
|
||||
paramIsFirstLoadOk:@(YES),
|
||||
paramPackageVersion:curPackageVersion}
|
||||
forKey:keyPushyInfo];
|
||||
}
|
||||
else {
|
||||
// roll back to bundle
|
||||
[defaults setObject:nil forKey:keyPushyInfo];
|
||||
}
|
||||
[defaults setObject:@(YES) forKey:keyRolledBackMarked];
|
||||
[defaults synchronize];
|
||||
// ...need clear files later
|
||||
loadVersion = [self rollback];
|
||||
}
|
||||
else if (isFirstTime && !ignoreRollback){
|
||||
// bundleURL may be called many times, ignore rollbacks before process restarted again.
|
||||
@@ -125,13 +98,15 @@ RCT_EXPORT_MODULE(RCTPushy);
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
if (loadVersioin.length) {
|
||||
NSString *downloadDir = [RCTPushy downloadDir];
|
||||
|
||||
NSString *bundlePath = [[downloadDir stringByAppendingPathComponent:loadVersioin] stringByAppendingPathComponent:BUNDLE_FILE_NAME];
|
||||
NSString *downloadDir = [RCTPushy downloadDir];
|
||||
while (loadVersion.length) {
|
||||
NSString *bundlePath = [[downloadDir stringByAppendingPathComponent:loadVersion] stringByAppendingPathComponent:BUNDLE_FILE_NAME];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:bundlePath isDirectory:NULL]) {
|
||||
NSURL *bundleURL = [NSURL fileURLWithPath:bundlePath];
|
||||
return bundleURL;
|
||||
} else {
|
||||
RCTLogError(@"RCTPushy -- bundle version %@ not found", loadVersion);
|
||||
loadVersion = [self rollback];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,6 +115,30 @@ RCT_EXPORT_MODULE(RCTPushy);
|
||||
return [RCTPushy binaryBundleURL];
|
||||
}
|
||||
|
||||
+ (NSString *) rollback {
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
|
||||
NSString *lastVersion = pushyInfo[paramLastVersion];
|
||||
NSString *curVersion = pushyInfo[paramCurrentVersion];
|
||||
NSString *curPackageVersion = [RCTPushy packageVersion];
|
||||
if (lastVersion.length) {
|
||||
// roll back to last version
|
||||
[defaults setObject:@{paramCurrentVersion:lastVersion,
|
||||
paramIsFirstTime:@(NO),
|
||||
paramIsFirstLoadOk:@(YES),
|
||||
paramPackageVersion:curPackageVersion}
|
||||
forKey:keyPushyInfo];
|
||||
}
|
||||
else {
|
||||
// roll back to bundle
|
||||
[defaults setObject:nil forKey:keyPushyInfo];
|
||||
}
|
||||
[defaults setObject:curVersion forKey:keyRolledBackMarked];
|
||||
[defaults synchronize];
|
||||
return lastVersion;
|
||||
}
|
||||
|
||||
+ (BOOL)requiresMainQueueSetup {
|
||||
// only set to YES if your module initialization relies on calling UIKit!
|
||||
return NO;
|
||||
@@ -153,18 +152,20 @@ RCT_EXPORT_MODULE(RCTPushy);
|
||||
ret[@"downloadRootDir"] = [RCTPushy downloadDir];
|
||||
ret[@"packageVersion"] = [RCTPushy packageVersion];
|
||||
ret[@"buildTime"] = [RCTPushy buildTime];
|
||||
ret[@"isRolledBack"] = [defaults objectForKey:keyRolledBackMarked];
|
||||
ret[@"rolledBackVersion"] = [defaults objectForKey:keyRolledBackMarked];
|
||||
ret[@"isFirstTime"] = [defaults objectForKey:keyFirstLoadMarked];
|
||||
ret[@"blockUpdate"] = [defaults objectForKey:keyBlockUpdate];
|
||||
ret[@"uuid"] = [defaults objectForKey:keyUuid];
|
||||
NSDictionary *pushyInfo = [defaults dictionaryForKey:keyPushyInfo];
|
||||
ret[@"currentVersion"] = [pushyInfo objectForKey:paramCurrentVersion];
|
||||
|
||||
// clear isFirstTimemarked
|
||||
if ([[defaults objectForKey:keyFirstLoadMarked] boolValue]) {
|
||||
if (ret[@"isFirstTime"]) {
|
||||
[defaults setObject:nil forKey:keyFirstLoadMarked];
|
||||
}
|
||||
|
||||
// clear rolledbackmark
|
||||
if ([[defaults objectForKey:keyRolledBackMarked] boolValue]) {
|
||||
if (ret[@"rolledBackVersion"] != nil) {
|
||||
[defaults setObject:nil forKey:keyRolledBackMarked];
|
||||
[self clearInvalidFiles];
|
||||
}
|
||||
@@ -188,6 +189,41 @@ RCT_EXPORT_MODULE(RCTPushy);
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setBlockUpdate:(NSDictionary *)options)
|
||||
{
|
||||
// NSMutableDictionary *blockUpdateInfo = [NSMutableDictionary new];
|
||||
// blockUpdateInfo[@"reason"] = options[@"reason"];
|
||||
// blockUpdateInfo[@"until"] = options[@"until"];
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setObject:options forKey:keyBlockUpdate];
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setUuid:(NSString *)uuid)
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setObject:uuid forKey:keyUuid];
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setLocalHashInfo:(NSString *)hash
|
||||
value:(NSString *)value)
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setObject:value forKey:[keyHashInfo stringByAppendingString:hash]];
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
|
||||
RCT_EXPORT_METHOD(getLocalHashInfo:(NSString *)hash
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
{
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
resolve([defaults stringForKey:[keyHashInfo stringByAppendingString:hash]]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(downloadUpdate:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock)resolve
|
||||
rejecter:(RCTPromiseRejectBlock)reject)
|
||||
@@ -232,8 +268,9 @@ RCT_EXPORT_METHOD(downloadPatchFromPpk:(NSDictionary *)options
|
||||
|
||||
RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options)
|
||||
{
|
||||
NSString *hashName = options[@"hashName"];
|
||||
if (hashName.length) {
|
||||
NSString *hash = options[@"hash"];
|
||||
|
||||
if (hash.length) {
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSString *lastVersion = nil;
|
||||
if ([defaults objectForKey:keyPushyInfo]) {
|
||||
@@ -242,7 +279,7 @@ RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options)
|
||||
}
|
||||
|
||||
NSMutableDictionary *newInfo = [[NSMutableDictionary alloc] init];
|
||||
newInfo[paramCurrentVersion] = hashName;
|
||||
newInfo[paramCurrentVersion] = hash;
|
||||
newInfo[paramLastVersion] = lastVersion;
|
||||
newInfo[paramIsFirstTime] = @(YES);
|
||||
newInfo[paramIsFirstLoadOk] = @(NO);
|
||||
@@ -255,15 +292,19 @@ RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options)
|
||||
|
||||
RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options)
|
||||
{
|
||||
NSString *hashName = options[@"hashName"];
|
||||
if (hashName.length) {
|
||||
NSString *hash = options[@"hash"];
|
||||
|
||||
if (hash.length) {
|
||||
[self setNeedUpdate:options];
|
||||
|
||||
// reload
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[_bridge setValue:[[self class] bundleURL] forKey:@"bundleURL"];
|
||||
[_bridge reload];
|
||||
});
|
||||
// reload 0.62+
|
||||
// RCTReloadCommandSetBundleURL([[self class] bundleURL]);
|
||||
// RCTTriggerReloadCommandListeners(@"pushy reload");
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.bridge setValue:[[self class] bundleURL] forKey:@"bundleURL"];
|
||||
[self.bridge reload];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,27 +312,57 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
{
|
||||
// up package info
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
NSMutableDictionary *packageInfo = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:keyPushyInfo]];
|
||||
[packageInfo setObject:@(NO) forKey:paramIsFirstTime];
|
||||
[packageInfo setObject:@(YES) forKey:paramIsFirstLoadOk];
|
||||
[defaults setObject:packageInfo forKey:keyPushyInfo];
|
||||
NSMutableDictionary *pushyInfo = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:keyPushyInfo]];
|
||||
[pushyInfo setObject:@(NO) forKey:paramIsFirstTime];
|
||||
[pushyInfo setObject:@(YES) forKey:paramIsFirstLoadOk];
|
||||
|
||||
NSString *lastVersion = pushyInfo[paramLastVersion];
|
||||
NSString *curVersion = pushyInfo[paramCurrentVersion];
|
||||
if (lastVersion != nil && ![lastVersion isEqualToString:curVersion]) {
|
||||
[pushyInfo removeObjectForKey:[keyHashInfo stringByAppendingString:lastVersion]];
|
||||
}
|
||||
[defaults setObject:pushyInfo forKey:keyPushyInfo];
|
||||
[defaults synchronize];
|
||||
|
||||
// clear other package dir
|
||||
[self clearInvalidFiles];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark - private
|
||||
- (NSArray<NSString *> *)supportedEvents
|
||||
{
|
||||
return @[
|
||||
EVENT_PROGRESS_DOWNLOAD,
|
||||
// EVENT_PROGRESS_UNZIP
|
||||
];
|
||||
}
|
||||
|
||||
// Will be called when this module's first listener is added.
|
||||
-(void)startObserving {
|
||||
hasListeners = YES;
|
||||
// Set up any upstream listeners or background tasks as necessary
|
||||
}
|
||||
|
||||
// Will be called when this module's last listener is removed, or on dealloc.
|
||||
-(void)stopObserving {
|
||||
hasListeners = NO;
|
||||
// Remove upstream listeners, stop unnecessary background tasks
|
||||
}
|
||||
|
||||
|
||||
- (void)doPushy:(PushyType)type options:(NSDictionary *)options callback:(void (^)(NSError *error))callback
|
||||
{
|
||||
NSString *updateUrl = [RCTConvert NSString:options[@"updateUrl"]];
|
||||
NSString *hashName = [RCTConvert NSString:options[@"hashName"]];
|
||||
if (updateUrl.length<=0 || hashName.length<=0) {
|
||||
NSString *hash = [RCTConvert NSString:options[@"hash"]];
|
||||
|
||||
if (updateUrl.length <= 0 || hash.length <= 0) {
|
||||
callback([self errorWithMessage:ERROR_OPTIONS]);
|
||||
return;
|
||||
}
|
||||
NSString *originHashName = [RCTConvert NSString:options[@"originHashName"]];
|
||||
if (type == PushyTypePatchFromPpk && originHashName<=0) {
|
||||
NSString *originHash = [RCTConvert NSString:options[@"originHash"]];
|
||||
if (type == PushyTypePatchFromPpk && originHash <= 0) {
|
||||
callback([self errorWithMessage:ERROR_OPTIONS]);
|
||||
return;
|
||||
}
|
||||
@@ -302,35 +373,38 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
callback([self errorWithMessage:ERROR_FILE_OPERATION]);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *zipFilePath = [dir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@",hashName, [self zipExtension:type]]];
|
||||
NSString *unzipDir = [dir stringByAppendingPathComponent:hashName];
|
||||
|
||||
NSString *zipFilePath = [dir stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@",hash, [self zipExtension:type]]];
|
||||
// NSString *unzipDir = [dir stringByAppendingPathComponent:hash];
|
||||
|
||||
RCTLogInfo(@"RCTPushy -- download file %@", updateUrl);
|
||||
[RCTPushyDownloader download:updateUrl savePath:zipFilePath progressHandler:^(long long receivedBytes, long long totalBytes) {
|
||||
[self.bridge.eventDispatcher sendAppEventWithName:EVENT_PROGRESS_DOWNLOAD
|
||||
body:@{
|
||||
PARAM_PROGRESS_HASHNAME:hashName,
|
||||
PARAM_PROGRESS_RECEIVED:[NSNumber numberWithLongLong:receivedBytes],
|
||||
PARAM_PROGRESS_TOTAL:[NSNumber numberWithLongLong:totalBytes]
|
||||
}];
|
||||
if (self->hasListeners) {
|
||||
[self sendEventWithName:EVENT_PROGRESS_DOWNLOAD body:@{
|
||||
PARAM_PROGRESS_HASH:hash,
|
||||
PARAM_PROGRESS_RECEIVED:[NSNumber numberWithLongLong:receivedBytes],
|
||||
PARAM_PROGRESS_TOTAL:[NSNumber numberWithLongLong:totalBytes]
|
||||
}];
|
||||
}
|
||||
} completionHandler:^(NSString *path, NSError *error) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
}
|
||||
else {
|
||||
RCTLogInfo(@"RCTPushy -- unzip file %@", zipFilePath);
|
||||
NSString *unzipFilePath = [dir stringByAppendingPathComponent:hashName];
|
||||
[_fileManager unzipFileAtPath:zipFilePath toDestination:unzipFilePath progressHandler:^(NSString *entry,long entryNumber, long total) {
|
||||
[self.bridge.eventDispatcher sendAppEventWithName:EVENT_PROGRESS_UNZIP
|
||||
body:@{
|
||||
PARAM_PROGRESS_HASHNAME:hashName,
|
||||
PARAM_PROGRESS_RECEIVED:[NSNumber numberWithLong:entryNumber],
|
||||
PARAM_PROGRESS_TOTAL:[NSNumber numberWithLong:total]
|
||||
}];
|
||||
NSString *unzipFilePath = [dir stringByAppendingPathComponent:hash];
|
||||
[self->_fileManager unzipFileAtPath:zipFilePath toDestination:unzipFilePath progressHandler:^(NSString *entry,long entryNumber, long total) {
|
||||
// if (self->hasListeners) {
|
||||
// [self sendEventWithName:EVENT_PROGRESS_UNZIP
|
||||
// body:@{
|
||||
// PARAM_PROGRESS_HASH:hash,
|
||||
// PARAM_PROGRESS_RECEIVED:[NSNumber numberWithLong:entryNumber],
|
||||
// PARAM_PROGRESS_TOTAL:[NSNumber numberWithLong:total]
|
||||
// }];
|
||||
// }
|
||||
|
||||
} completionHandler:^(NSString *path, BOOL succeeded, NSError *error) {
|
||||
dispatch_async(_methodQueue, ^{
|
||||
dispatch_async(self->_methodQueue, ^{
|
||||
if (error) {
|
||||
callback(error);
|
||||
}
|
||||
@@ -340,16 +414,16 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
{
|
||||
NSString *sourceOrigin = [[NSBundle mainBundle] resourcePath];
|
||||
NSString *bundleOrigin = [[RCTPushy binaryBundleURL] path];
|
||||
[self patch:hashName fromBundle:bundleOrigin source:sourceOrigin callback:callback];
|
||||
[self patch:hash fromBundle:bundleOrigin source:sourceOrigin callback:callback];
|
||||
}
|
||||
break;
|
||||
case PushyTypePatchFromPpk:
|
||||
{
|
||||
NSString *lastVertionDir = [dir stringByAppendingPathComponent:originHashName];
|
||||
NSString *lastVersionDir = [dir stringByAppendingPathComponent:originHash];
|
||||
|
||||
NSString *sourceOrigin = lastVertionDir;
|
||||
NSString *bundleOrigin = [lastVertionDir stringByAppendingPathComponent:BUNDLE_FILE_NAME];
|
||||
[self patch:hashName fromBundle:bundleOrigin source:sourceOrigin callback:callback];
|
||||
NSString *sourceOrigin = lastVersionDir;
|
||||
NSString *bundleOrigin = [lastVersionDir stringByAppendingPathComponent:BUNDLE_FILE_NAME];
|
||||
[self patch:hash fromBundle:bundleOrigin source:sourceOrigin callback:callback];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -363,14 +437,15 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)patch:(NSString *)hashName fromBundle:(NSString *)bundleOrigin source:(NSString *)sourceOrigin callback:(void (^)(NSError *error))callback
|
||||
- (void)_dopatch:(NSString *)hash fromBundle:(NSString *)bundleOrigin source:(NSString *)sourceOrigin
|
||||
callback:(void (^)(NSError *error))callback
|
||||
{
|
||||
NSString *unzipDir = [[RCTPushy downloadDir] stringByAppendingPathComponent:hashName];
|
||||
NSString *unzipDir = [[RCTPushy downloadDir] stringByAppendingPathComponent:hash];
|
||||
NSString *sourcePatch = [unzipDir stringByAppendingPathComponent:SOURCE_PATCH_NAME];
|
||||
NSString *bundlePatch = [unzipDir stringByAppendingPathComponent:BUNDLE_PATCH_NAME];
|
||||
|
||||
NSString *destination = [unzipDir stringByAppendingPathComponent:BUNDLE_FILE_NAME];
|
||||
[_fileManager bsdiffFileAtPath:bundlePatch fromOrigin:bundleOrigin toDestination:destination completionHandler:^(BOOL success) {
|
||||
void (^completionHandler)(BOOL success) = ^(BOOL success) {
|
||||
if (success) {
|
||||
NSData *data = [NSData dataWithContentsOfFile:sourcePatch];
|
||||
NSError *error = nil;
|
||||
@@ -383,7 +458,7 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
NSDictionary *copies = json[@"copies"];
|
||||
NSDictionary *deletes = json[@"deletes"];
|
||||
|
||||
[_fileManager copyFiles:copies fromDir:sourceOrigin toDir:unzipDir deletes:deletes completionHandler:^(NSError *error) {
|
||||
[self->_fileManager copyFiles:copies fromDir:sourceOrigin toDir:unzipDir deletes:deletes completionHandler:^(NSError *error) {
|
||||
if (error) {
|
||||
callback(error);
|
||||
}
|
||||
@@ -393,9 +468,15 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
}];
|
||||
}
|
||||
else {
|
||||
callback([self errorWithMessage:ERROR_BSDIFF]);
|
||||
callback([self errorWithMessage:ERROR_HDIFFPATCH]);
|
||||
}
|
||||
}];
|
||||
};
|
||||
[_fileManager hdiffFileAtPath:bundlePatch fromOrigin:bundleOrigin toDestination:destination completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)patch:(NSString *)hash fromBundle:(NSString *)bundleOrigin source:(NSString *)sourceOrigin callback:(void (^)(NSError *error))callback
|
||||
{
|
||||
[self _dopatch:hash fromBundle:bundleOrigin source:sourceOrigin callback:callback];
|
||||
}
|
||||
|
||||
- (void)clearInvalidFiles
|
||||
@@ -424,7 +505,7 @@ RCT_EXPORT_METHOD(markSuccess)
|
||||
case PushyTypeFullDownload:
|
||||
return @".ppk";
|
||||
case PushyTypePatchFromPackage:
|
||||
return @".apk.patch";
|
||||
return @".ipa.patch";
|
||||
case PushyTypePatchFromPpk:
|
||||
return @".ppk.patch";
|
||||
default:
|
||||
|
@@ -1,11 +1,3 @@
|
||||
//
|
||||
// RCTPushyDownloader.h
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by lvbingru on 16/2/23.
|
||||
// Copyright © 2016年 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface RCTPushyDownloader : NSObject
|
||||
|
@@ -1,11 +1,3 @@
|
||||
//
|
||||
// RCTPushyDownloader.m
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by lvbingru on 16/2/23.
|
||||
// Copyright © 2016年 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RCTPushyDownloader.h"
|
||||
|
||||
@interface RCTPushyDownloader()<NSURLSessionDelegate>
|
||||
|
@@ -1,11 +1,3 @@
|
||||
//
|
||||
// RCTPushyManager.h
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by lvbingru on 16/4/1.
|
||||
// Copyright © 2016年 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface RCTPushyManager : NSObject
|
||||
@@ -18,10 +10,10 @@
|
||||
progressHandler:(void (^)(NSString *entry, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler;
|
||||
|
||||
- (void)bsdiffFileAtPath:(NSString *)path
|
||||
fromOrigin:(NSString *)origin
|
||||
toDestination:(NSString *)destination
|
||||
completionHandler:(void (^)(BOOL success))completionHandler;
|
||||
- (void)hdiffFileAtPath:(NSString *)path
|
||||
fromOrigin:(NSString *)origin
|
||||
toDestination:(NSString *)destination
|
||||
completionHandler:(void (^)(BOOL success))completionHandler;
|
||||
|
||||
- (void)copyFiles:(NSDictionary *)filesDic
|
||||
fromDir:(NSString *)fromDir
|
||||
|
@@ -1,15 +1,6 @@
|
||||
//
|
||||
// RCTPushyManager.m
|
||||
// RCTPushy
|
||||
//
|
||||
// Created by lvbingru on 16/4/1.
|
||||
// Copyright © 2016年 erica. All rights reserved.
|
||||
//
|
||||
|
||||
#import "RCTPushyManager.h"
|
||||
#import "ZipArchive.h"
|
||||
#import "BSDiff.h"
|
||||
#import "bspatch.h"
|
||||
#import "HDiffPatch.h"
|
||||
|
||||
@implementation RCTPushyManager {
|
||||
dispatch_queue_t _opQueue;
|
||||
@@ -75,13 +66,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
- (void)bsdiffFileAtPath:(NSString *)path
|
||||
fromOrigin:(NSString *)origin
|
||||
toDestination:(NSString *)destination
|
||||
completionHandler:(void (^)(BOOL success))completionHandler
|
||||
- (void)hdiffFileAtPath:(NSString *)path
|
||||
fromOrigin:(NSString *)origin
|
||||
toDestination:(NSString *)destination
|
||||
completionHandler:(void (^)(BOOL success))completionHandler
|
||||
{
|
||||
dispatch_async(_opQueue, ^{
|
||||
BOOL success = [BSDiff bsdiffPatch:path origin:origin toDestination:destination];
|
||||
BOOL success = [HDiffPatch hdiffPatch:path origin:origin toDestination:destination];
|
||||
if (completionHandler) {
|
||||
completionHandler(success);
|
||||
}
|
||||
@@ -99,16 +90,9 @@ completionHandler:(void (^)(NSError *error))completionHandler
|
||||
|
||||
// merge old files
|
||||
if (deletes!= nil) {
|
||||
NSError *error = nil;
|
||||
NSString *srcDir = [fromDir stringByAppendingPathComponent:@"assets"];
|
||||
NSString *desDir = [toDir stringByAppendingPathComponent:@"assets"];
|
||||
[self _mergeContentsOfPath:srcDir intoPath:desDir deletes:deletes error:&error];
|
||||
if (error) {
|
||||
if (completionHandler) {
|
||||
completionHandler(error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
[self _mergeContentsOfPath:srcDir intoPath:desDir deletes:deletes];
|
||||
}
|
||||
|
||||
// copy files
|
||||
@@ -126,10 +110,11 @@ completionHandler:(void (^)(NSError *error))completionHandler
|
||||
NSError *error = nil;
|
||||
[fm copyItemAtPath:fromPath toPath:toPath error:&error];
|
||||
if (error) {
|
||||
if (completionHandler) {
|
||||
completionHandler(error);
|
||||
}
|
||||
return;
|
||||
NSLog(@"Pushy copy error: %@", error.localizedDescription);
|
||||
// if (completionHandler) {
|
||||
// completionHandler(error);
|
||||
// }
|
||||
// return;
|
||||
}
|
||||
}
|
||||
if (completionHandler) {
|
||||
@@ -150,7 +135,7 @@ completionHandler:(void (^)(NSError *error))completionHandler
|
||||
});
|
||||
}
|
||||
|
||||
- (void)_mergeContentsOfPath:(NSString *)srcDir intoPath:(NSString *)dstDir deletes:(NSDictionary *)deletes error:(NSError**)err
|
||||
- (void)_mergeContentsOfPath:(NSString *)srcDir intoPath:(NSString *)dstDir deletes:(NSDictionary *)deletes
|
||||
{
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSDirectoryEnumerator *srcDirEnum = [fm enumeratorAtPath:srcDir];
|
||||
@@ -159,7 +144,9 @@ completionHandler:(void (^)(NSError *error))completionHandler
|
||||
|
||||
NSString *srcFullPath = [srcDir stringByAppendingPathComponent:subPath];
|
||||
NSString *potentialDstPath = [dstDir stringByAppendingPathComponent:subPath];
|
||||
|
||||
|
||||
NSError *error = nil;
|
||||
|
||||
BOOL inDeletes = NO;
|
||||
if (deletes) {
|
||||
NSString *path = [@"assets" stringByAppendingPathComponent:subPath];
|
||||
@@ -171,18 +158,19 @@ completionHandler:(void (^)(NSError *error))completionHandler
|
||||
BOOL isDirectory = ([fm fileExistsAtPath:srcFullPath isDirectory:&isDirectory] && isDirectory);
|
||||
if (isDirectory) {
|
||||
if (![fm fileExistsAtPath:potentialDstPath isDirectory:nil]) {
|
||||
[fm createDirectoryAtPath:potentialDstPath withIntermediateDirectories:YES attributes:nil error:err];
|
||||
if (err && *err) {
|
||||
return;
|
||||
[fm createDirectoryAtPath:potentialDstPath withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Pushy merge error: %@", error.localizedDescription);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (![fm fileExistsAtPath:potentialDstPath]) {
|
||||
[fm copyItemAtPath:srcFullPath toPath:potentialDstPath error:err];
|
||||
if (err && *err) {
|
||||
return;
|
||||
[fm copyItemAtPath:srcFullPath toPath:potentialDstPath error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Pushy merge error: %@", error.localizedDescription);
|
||||
// return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,81 +0,0 @@
|
||||
#ifndef SSZipCommon
|
||||
#define SSZipCommon
|
||||
|
||||
/* tm_unz contain date/time info */
|
||||
typedef struct tm_unz_s
|
||||
{
|
||||
unsigned int tm_sec; /* seconds after the minute - [0,59] */
|
||||
unsigned int tm_min; /* minutes after the hour - [0,59] */
|
||||
unsigned int tm_hour; /* hours since midnight - [0,23] */
|
||||
unsigned int tm_mday; /* day of the month - [1,31] */
|
||||
unsigned int tm_mon; /* months since January - [0,11] */
|
||||
unsigned int tm_year; /* years - [1980..2044] */
|
||||
} tm_unz;
|
||||
|
||||
typedef struct unz_file_info_s
|
||||
{
|
||||
unsigned long version; /* version made by 2 bytes */
|
||||
unsigned long version_needed; /* version needed to extract 2 bytes */
|
||||
unsigned long flag; /* general purpose bit flag 2 bytes */
|
||||
unsigned long compression_method; /* compression method 2 bytes */
|
||||
unsigned long dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||
unsigned long crc; /* crc-32 4 bytes */
|
||||
unsigned long compressed_size; /* compressed size 4 bytes */
|
||||
unsigned long uncompressed_size; /* uncompressed size 4 bytes */
|
||||
unsigned long size_filename; /* filename length 2 bytes */
|
||||
unsigned long size_file_extra; /* extra field length 2 bytes */
|
||||
unsigned long size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
unsigned long disk_num_start; /* disk number start 2 bytes */
|
||||
unsigned long internal_fa; /* internal file attributes 2 bytes */
|
||||
unsigned long external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
} unz_file_info;
|
||||
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
typedef struct unz_file_info64_s
|
||||
{
|
||||
unsigned long version; /* version made by 2 bytes */
|
||||
unsigned long version_needed; /* version needed to extract 2 bytes */
|
||||
unsigned long flag; /* general purpose bit flag 2 bytes */
|
||||
unsigned long compression_method; /* compression method 2 bytes */
|
||||
unsigned long dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||
unsigned long crc; /* crc-32 4 bytes */
|
||||
unsigned long long compressed_size; /* compressed size 8 bytes */
|
||||
unsigned long long uncompressed_size; /* uncompressed size 8 bytes */
|
||||
unsigned long size_filename; /* filename length 2 bytes */
|
||||
unsigned long size_file_extra; /* extra field length 2 bytes */
|
||||
unsigned long size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
unsigned long disk_num_start; /* disk number start 2 bytes */
|
||||
unsigned long internal_fa; /* internal file attributes 2 bytes */
|
||||
unsigned long external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
unsigned long long disk_offset;
|
||||
unsigned long size_file_extra_internal;
|
||||
} unz_file_info64;
|
||||
|
||||
typedef struct unz_global_info_s
|
||||
{
|
||||
unsigned long number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
|
||||
unsigned long number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/
|
||||
|
||||
|
||||
unsigned long size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
typedef struct unz_global_info64
|
||||
{
|
||||
unsigned long long number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
|
||||
unsigned long number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP*/
|
||||
|
||||
unsigned long size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info64;
|
||||
|
||||
#endif
|
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
@@ -1,77 +0,0 @@
|
||||
//
|
||||
// SSZipArchive.h
|
||||
// SSZipArchive
|
||||
//
|
||||
// Created by Sam Soffes on 7/21/10.
|
||||
// Copyright (c) Sam Soffes 2010-2015. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef _SSZIPARCHIVE_H
|
||||
#define _SSZIPARCHIVE_H
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include "Common.h"
|
||||
|
||||
@protocol SSZipArchiveDelegate;
|
||||
|
||||
@interface SSZipArchive : NSObject
|
||||
|
||||
// Unzip
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination;
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate;
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError * *)error;
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError * *)error delegate:(id<SSZipArchiveDelegate>)delegate;
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler;
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
overwrite:(BOOL)overwrite
|
||||
password:(NSString *)password
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler;
|
||||
|
||||
// Zip
|
||||
|
||||
// without password
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirector;
|
||||
|
||||
// with password, password could be nil
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths withPassword:(NSString *)password;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(NSString *)password;
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(NSString *)password;
|
||||
|
||||
- (instancetype)initWithPath:(NSString *)path;
|
||||
@property (NS_NONATOMIC_IOSONLY, readonly, getter = isOpen) BOOL open;
|
||||
- (BOOL)writeFile:(NSString *)path withPassword:(NSString *)password;
|
||||
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(NSString *)password;
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(NSString *)fileName withPassword:(NSString *)password;
|
||||
- (BOOL)writeData:(NSData *)data filename:(NSString *)filename withPassword:(NSString *)password;
|
||||
@property (NS_NONATOMIC_IOSONLY, readonly, getter = isClosed) BOOL close;
|
||||
|
||||
@end
|
||||
|
||||
@protocol SSZipArchiveDelegate <NSObject>
|
||||
|
||||
@optional
|
||||
|
||||
- (void)zipArchiveWillUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo;
|
||||
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath;
|
||||
|
||||
- (BOOL)zipArchiveShouldUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
|
||||
- (void)zipArchiveWillUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
|
||||
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath fileInfo:(unz_file_info)fileInfo;
|
||||
- (void)zipArchiveDidUnzipFileAtIndex:(NSInteger)fileIndex totalFiles:(NSInteger)totalFiles archivePath:(NSString *)archivePath unzippedFilePath:(NSString *)unzippedFilePath;
|
||||
|
||||
- (void)zipArchiveProgressEvent:(unsigned long long)loaded total:(unsigned long long)total;
|
||||
- (void)zipArchiveDidUnzipArchiveFile:(NSString *)zipFile entryPath:(NSString *)entryPath destPath:(NSString *)destPath;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* _SSZIPARCHIVE_H */
|
@@ -1,711 +0,0 @@
|
||||
//
|
||||
// SSZipArchive.m
|
||||
// SSZipArchive
|
||||
//
|
||||
// Created by Sam Soffes on 7/21/10.
|
||||
// Copyright (c) Sam Soffes 2010-2015. All rights reserved.
|
||||
//
|
||||
#import "SSZipArchive.h"
|
||||
#include "unzip.h"
|
||||
#include "zip.h"
|
||||
#import "zlib.h"
|
||||
#import "zconf.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define CHUNK 16384
|
||||
|
||||
@interface SSZipArchive ()
|
||||
+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime;
|
||||
@end
|
||||
|
||||
@implementation SSZipArchive
|
||||
{
|
||||
NSString *_path;
|
||||
NSString *_filename;
|
||||
zipFile _zip;
|
||||
}
|
||||
|
||||
#pragma mark - Unzipping
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination delegate:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:nil progressHandler:nil completionHandler:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination delegate:(id<SSZipArchiveDelegate>)delegate
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:delegate progressHandler:nil completionHandler:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path toDestination:(NSString *)destination overwrite:(BOOL)overwrite password:(NSString *)password error:(NSError **)error delegate:(id<SSZipArchiveDelegate>)delegate
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:error delegate:delegate progressHandler:nil completionHandler:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
overwrite:(BOOL)overwrite
|
||||
password:(NSString *)password
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination overwrite:overwrite password:password error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler
|
||||
{
|
||||
return [self unzipFileAtPath:path toDestination:destination overwrite:YES password:nil error:nil delegate:nil progressHandler:progressHandler completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
+ (BOOL)unzipFileAtPath:(NSString *)path
|
||||
toDestination:(NSString *)destination
|
||||
overwrite:(BOOL)overwrite
|
||||
password:(NSString *)password
|
||||
error:(NSError **)error
|
||||
delegate:(id<SSZipArchiveDelegate>)delegate
|
||||
progressHandler:(void (^)(NSString *entry, unz_file_info zipInfo, long entryNumber, long total))progressHandler
|
||||
completionHandler:(void (^)(NSString *path, BOOL succeeded, NSError *error))completionHandler
|
||||
{
|
||||
// Begin opening
|
||||
zipFile zip = unzOpen((const char*)[path UTF8String]);
|
||||
if (zip == NULL)
|
||||
{
|
||||
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open zip file"};
|
||||
NSError *err = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-1 userInfo:userInfo];
|
||||
if (error)
|
||||
{
|
||||
*error = err;
|
||||
}
|
||||
if (completionHandler)
|
||||
{
|
||||
completionHandler(nil, NO, err);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
NSDictionary * fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
|
||||
unsigned long long fileSize = [fileAttributes[NSFileSize] unsignedLongLongValue];
|
||||
unsigned long long currentPosition = 0;
|
||||
|
||||
unz_global_info globalInfo = {0ul, 0ul};
|
||||
unzGetGlobalInfo(zip, &globalInfo);
|
||||
|
||||
// Begin unzipping
|
||||
if (unzGoToFirstFile(zip) != UNZ_OK)
|
||||
{
|
||||
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"failed to open first file in zip file"};
|
||||
NSError *err = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-2 userInfo:userInfo];
|
||||
if (error)
|
||||
{
|
||||
*error = err;
|
||||
}
|
||||
if (completionHandler)
|
||||
{
|
||||
completionHandler(nil, NO, err);
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
BOOL success = YES;
|
||||
BOOL canceled = NO;
|
||||
int ret = 0;
|
||||
int crc_ret =0;
|
||||
unsigned char buffer[4096] = {0};
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSMutableSet *directoriesModificationDates = [[NSMutableSet alloc] init];
|
||||
|
||||
// Message delegate
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipArchiveAtPath:zipInfo:)]) {
|
||||
[delegate zipArchiveWillUnzipArchiveAtPath:path zipInfo:globalInfo];
|
||||
}
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {
|
||||
[delegate zipArchiveProgressEvent:currentPosition total:fileSize];
|
||||
}
|
||||
|
||||
NSInteger currentFileNumber = 0;
|
||||
do {
|
||||
@autoreleasepool {
|
||||
if ([password length] == 0) {
|
||||
ret = unzOpenCurrentFile(zip);
|
||||
} else {
|
||||
ret = unzOpenCurrentFilePassword(zip, [password cStringUsingEncoding:NSASCIIStringEncoding]);
|
||||
}
|
||||
|
||||
if (ret != UNZ_OK) {
|
||||
success = NO;
|
||||
break;
|
||||
}
|
||||
|
||||
// Reading data and write to file
|
||||
unz_file_info fileInfo;
|
||||
memset(&fileInfo, 0, sizeof(unz_file_info));
|
||||
|
||||
ret = unzGetCurrentFileInfo(zip, &fileInfo, NULL, 0, NULL, 0, NULL, 0);
|
||||
if (ret != UNZ_OK) {
|
||||
success = NO;
|
||||
unzCloseCurrentFile(zip);
|
||||
break;
|
||||
}
|
||||
|
||||
currentPosition += fileInfo.compressed_size;
|
||||
|
||||
// Message delegate
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveShouldUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
|
||||
if (![delegate zipArchiveShouldUnzipFileAtIndex:currentFileNumber
|
||||
totalFiles:(NSInteger)globalInfo.number_entry
|
||||
archivePath:path fileInfo:fileInfo]) {
|
||||
success = NO;
|
||||
canceled = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveWillUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
|
||||
[delegate zipArchiveWillUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
|
||||
archivePath:path fileInfo:fileInfo];
|
||||
}
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {
|
||||
[delegate zipArchiveProgressEvent:(NSInteger)currentPosition total:(NSInteger)fileSize];
|
||||
}
|
||||
|
||||
char *filename = (char *)malloc(fileInfo.size_filename + 1);
|
||||
if (filename == NULL)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
unzGetCurrentFileInfo(zip, &fileInfo, filename, fileInfo.size_filename + 1, NULL, 0, NULL, 0);
|
||||
filename[fileInfo.size_filename] = '\0';
|
||||
|
||||
//
|
||||
// Determine whether this is a symbolic link:
|
||||
// - File is stored with 'version made by' value of UNIX (3),
|
||||
// as per http://www.pkware.com/documents/casestudies/APPNOTE.TXT
|
||||
// in the upper byte of the version field.
|
||||
// - BSD4.4 st_mode constants are stored in the high 16 bits of the
|
||||
// external file attributes (defacto standard, verified against libarchive)
|
||||
//
|
||||
// The original constants can be found here:
|
||||
// http://minnie.tuhs.org/cgi-bin/utree.pl?file=4.4BSD/usr/include/sys/stat.h
|
||||
//
|
||||
const uLong ZipUNIXVersion = 3;
|
||||
const uLong BSD_SFMT = 0170000;
|
||||
const uLong BSD_IFLNK = 0120000;
|
||||
|
||||
BOOL fileIsSymbolicLink = NO;
|
||||
if (((fileInfo.version >> 8) == ZipUNIXVersion) && BSD_IFLNK == (BSD_SFMT & (fileInfo.external_fa >> 16))) {
|
||||
fileIsSymbolicLink = NO;
|
||||
}
|
||||
|
||||
// Check if it contains directory
|
||||
NSString *strPath = @(filename);
|
||||
BOOL isDirectory = NO;
|
||||
if (filename[fileInfo.size_filename-1] == '/' || filename[fileInfo.size_filename-1] == '\\') {
|
||||
isDirectory = YES;
|
||||
}
|
||||
free(filename);
|
||||
|
||||
// Contains a path
|
||||
if ([strPath rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"/\\"]].location != NSNotFound) {
|
||||
strPath = [strPath stringByReplacingOccurrencesOfString:@"\\" withString:@"/"];
|
||||
}
|
||||
|
||||
NSString *fullPath = [destination stringByAppendingPathComponent:strPath];
|
||||
NSError *err = nil;
|
||||
NSDate *modDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
|
||||
NSDictionary *directoryAttr = @{NSFileCreationDate: modDate, NSFileModificationDate: modDate};
|
||||
|
||||
if (isDirectory) {
|
||||
[fileManager createDirectoryAtPath:fullPath withIntermediateDirectories:YES attributes:directoryAttr error:&err];
|
||||
} else {
|
||||
[fileManager createDirectoryAtPath:[fullPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:directoryAttr error:&err];
|
||||
}
|
||||
if (nil != err) {
|
||||
NSLog(@"[SSZipArchive] Error: %@", err.localizedDescription);
|
||||
}
|
||||
|
||||
if(!fileIsSymbolicLink)
|
||||
[directoriesModificationDates addObject: @{@"path": fullPath, @"modDate": modDate}];
|
||||
|
||||
if ([fileManager fileExistsAtPath:fullPath] && !isDirectory && !overwrite) {
|
||||
//FIXME: couldBe CRC Check?
|
||||
unzCloseCurrentFile(zip);
|
||||
ret = unzGoToNextFile(zip);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fileIsSymbolicLink) {
|
||||
FILE *fp = fopen((const char*)[fullPath UTF8String], "wb");
|
||||
while (fp) {
|
||||
int readBytes = unzReadCurrentFile(zip, buffer, 4096);
|
||||
|
||||
if (readBytes > 0) {
|
||||
fwrite(buffer, readBytes, 1, fp );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fp) {
|
||||
if ([[[fullPath pathExtension] lowercaseString] isEqualToString:@"zip"]) {
|
||||
NSLog(@"Unzipping nested .zip file: %@", [fullPath lastPathComponent]);
|
||||
if ([self unzipFileAtPath:fullPath toDestination:[fullPath stringByDeletingLastPathComponent] overwrite:overwrite password:password error:nil delegate:nil]) {
|
||||
[[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
// Set the original datetime property
|
||||
if (fileInfo.dosDate != 0) {
|
||||
NSDate *orgDate = [[self class] _dateWithMSDOSFormat:(UInt32)fileInfo.dosDate];
|
||||
NSDictionary *attr = @{NSFileModificationDate: orgDate};
|
||||
|
||||
if (attr) {
|
||||
if ([fileManager setAttributes:attr ofItemAtPath:fullPath error:nil] == NO) {
|
||||
// Can't set attributes
|
||||
NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting modification date");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the original permissions on the file
|
||||
uLong permissions = fileInfo.external_fa >> 16;
|
||||
if (permissions != 0) {
|
||||
// Store it into a NSNumber
|
||||
NSNumber *permissionsValue = @(permissions);
|
||||
|
||||
// Retrieve any existing attributes
|
||||
NSMutableDictionary *attrs = [[NSMutableDictionary alloc] initWithDictionary:[fileManager attributesOfItemAtPath:fullPath error:nil]];
|
||||
|
||||
// Set the value in the attributes dict
|
||||
attrs[NSFilePosixPermissions] = permissionsValue;
|
||||
|
||||
// Update attributes
|
||||
if ([fileManager setAttributes:attrs ofItemAtPath:fullPath error:nil] == NO) {
|
||||
// Unable to set the permissions attribute
|
||||
NSLog(@"[SSZipArchive] Failed to set attributes - whilst setting permissions");
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[attrs release];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assemble the path for the symbolic link
|
||||
NSMutableString* destinationPath = [NSMutableString string];
|
||||
int bytesRead = 0;
|
||||
while((bytesRead = unzReadCurrentFile(zip, buffer, 4096)) > 0)
|
||||
{
|
||||
buffer[bytesRead] = (int)0;
|
||||
[destinationPath appendString:@((const char*)buffer)];
|
||||
}
|
||||
|
||||
// Create the symbolic link (making sure it stays relative if it was relative before)
|
||||
int symlinkError = symlink([destinationPath cStringUsingEncoding:NSUTF8StringEncoding],
|
||||
[fullPath cStringUsingEncoding:NSUTF8StringEncoding]);
|
||||
|
||||
if(symlinkError != 0)
|
||||
{
|
||||
NSLog(@"Failed to create symbolic link at \"%@\" to \"%@\". symlink() error code: %d", fullPath, destinationPath, errno);
|
||||
}
|
||||
}
|
||||
|
||||
crc_ret = unzCloseCurrentFile( zip );
|
||||
if (crc_ret == UNZ_CRCERROR) {
|
||||
//CRC ERROR
|
||||
success = NO;
|
||||
break;
|
||||
}
|
||||
ret = unzGoToNextFile( zip );
|
||||
|
||||
// Message delegate
|
||||
if ([delegate respondsToSelector:@selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:fileInfo:)]) {
|
||||
[delegate zipArchiveDidUnzipFileAtIndex:currentFileNumber totalFiles:(NSInteger)globalInfo.number_entry
|
||||
archivePath:path fileInfo:fileInfo];
|
||||
} else if ([delegate respondsToSelector: @selector(zipArchiveDidUnzipFileAtIndex:totalFiles:archivePath:unzippedFilePath:)]) {
|
||||
[delegate zipArchiveDidUnzipFileAtIndex: currentFileNumber totalFiles: (NSInteger)globalInfo.number_entry
|
||||
archivePath:path unzippedFilePath: fullPath];
|
||||
}
|
||||
|
||||
currentFileNumber++;
|
||||
if (progressHandler)
|
||||
{
|
||||
progressHandler(strPath, fileInfo, currentFileNumber, globalInfo.number_entry);
|
||||
}
|
||||
}
|
||||
} while(ret == UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE);
|
||||
|
||||
// Close
|
||||
unzClose(zip);
|
||||
|
||||
// The process of decompressing the .zip archive causes the modification times on the folders
|
||||
// to be set to the present time. So, when we are done, they need to be explicitly set.
|
||||
// set the modification date on all of the directories.
|
||||
NSError * err = nil;
|
||||
for (NSDictionary * d in directoriesModificationDates) {
|
||||
if (![[NSFileManager defaultManager] setAttributes:@{NSFileModificationDate: d[@"modDate"]} ofItemAtPath:d[@"path"] error:&err]) {
|
||||
NSLog(@"[SSZipArchive] Set attributes failed for directory: %@.", d[@"path"]);
|
||||
}
|
||||
if (err) {
|
||||
NSLog(@"[SSZipArchive] Error setting directory file modification date attribute: %@",err.localizedDescription);
|
||||
}
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[directoriesModificationDates release];
|
||||
#endif
|
||||
|
||||
// Message delegate
|
||||
if (success && [delegate respondsToSelector:@selector(zipArchiveDidUnzipArchiveAtPath:zipInfo:unzippedPath:)]) {
|
||||
[delegate zipArchiveDidUnzipArchiveAtPath:path zipInfo:globalInfo unzippedPath:destination];
|
||||
}
|
||||
// final progress event = 100%
|
||||
if (!canceled && [delegate respondsToSelector:@selector(zipArchiveProgressEvent:total:)]) {
|
||||
[delegate zipArchiveProgressEvent:fileSize total:fileSize];
|
||||
}
|
||||
|
||||
NSError *retErr = nil;
|
||||
if (crc_ret == UNZ_CRCERROR)
|
||||
{
|
||||
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: @"crc check failed for file"};
|
||||
retErr = [NSError errorWithDomain:@"SSZipArchiveErrorDomain" code:-3 userInfo:userInfo];
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
*error = retErr;
|
||||
}
|
||||
if (completionHandler)
|
||||
{
|
||||
completionHandler(path, success, retErr);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
#pragma mark - Zipping
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths
|
||||
{
|
||||
return [SSZipArchive createZipFileAtPath:path withFilesAtPaths:paths withPassword:nil];
|
||||
}
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath{
|
||||
return [SSZipArchive createZipFileAtPath:path withContentsOfDirectory:directoryPath withPassword:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirector{
|
||||
return [SSZipArchive createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:keepParentDirector withPassword:nil];
|
||||
}
|
||||
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withFilesAtPaths:(NSArray *)paths withPassword:(NSString *)password
|
||||
{
|
||||
BOOL success = NO;
|
||||
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
|
||||
if ([zipArchive open]) {
|
||||
for (NSString *filePath in paths) {
|
||||
[zipArchive writeFile:filePath withPassword:password];
|
||||
}
|
||||
success = [zipArchive close];
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[zipArchive release];
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath withPassword:(NSString *)password{
|
||||
return [self createZipFileAtPath:path withContentsOfDirectory:directoryPath keepParentDirectory:NO withPassword:password];
|
||||
}
|
||||
|
||||
|
||||
+ (BOOL)createZipFileAtPath:(NSString *)path withContentsOfDirectory:(NSString *)directoryPath keepParentDirectory:(BOOL)keepParentDirectory withPassword:(NSString *)password{
|
||||
BOOL success = NO;
|
||||
|
||||
NSFileManager *fileManager = nil;
|
||||
SSZipArchive *zipArchive = [[SSZipArchive alloc] initWithPath:path];
|
||||
|
||||
if ([zipArchive open]) {
|
||||
// use a local filemanager (queue/thread compatibility)
|
||||
fileManager = [[NSFileManager alloc] init];
|
||||
NSDirectoryEnumerator *dirEnumerator = [fileManager enumeratorAtPath:directoryPath];
|
||||
NSString *fileName;
|
||||
while ((fileName = [dirEnumerator nextObject])) {
|
||||
BOOL isDir;
|
||||
NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:fileName];
|
||||
[fileManager fileExistsAtPath:fullFilePath isDirectory:&isDir];
|
||||
if (!isDir) {
|
||||
if (keepParentDirectory)
|
||||
{
|
||||
fileName = [[directoryPath lastPathComponent] stringByAppendingPathComponent:fileName];
|
||||
}
|
||||
[zipArchive writeFileAtPath:fullFilePath withFileName:fileName withPassword:password];
|
||||
}
|
||||
else
|
||||
{
|
||||
if([[NSFileManager defaultManager] subpathsOfDirectoryAtPath:fullFilePath error:nil].count == 0)
|
||||
{
|
||||
NSString *tempName = [fullFilePath stringByAppendingPathComponent:@".DS_Store"];
|
||||
[@"" writeToFile:tempName atomically:YES encoding:NSUTF8StringEncoding error:nil];
|
||||
[zipArchive writeFileAtPath:tempName withFileName:[fileName stringByAppendingPathComponent:@".DS_Store"] withPassword:password];
|
||||
[[NSFileManager defaultManager] removeItemAtPath:tempName error:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
success = [zipArchive close];
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[fileManager release];
|
||||
[zipArchive release];
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
- (instancetype)initWithPath:(NSString *)path
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_path = [path copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
- (void)dealloc
|
||||
{
|
||||
[_path release];
|
||||
[super dealloc];
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
- (BOOL)open
|
||||
{
|
||||
NSAssert((_zip == NULL), @"Attempting open an archive which is already open");
|
||||
_zip = zipOpen([_path UTF8String], APPEND_STATUS_CREATE);
|
||||
return (NULL != _zip);
|
||||
}
|
||||
|
||||
|
||||
- (void)zipInfo:(zip_fileinfo*)zipInfo setDate:(NSDate*)date
|
||||
{
|
||||
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
|
||||
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
|
||||
uint flags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
|
||||
#else
|
||||
uint flags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
|
||||
#endif
|
||||
NSDateComponents *components = [currentCalendar components:flags fromDate:date];
|
||||
zipInfo->tmz_date.tm_sec = (unsigned int)components.second;
|
||||
zipInfo->tmz_date.tm_min = (unsigned int)components.minute;
|
||||
zipInfo->tmz_date.tm_hour = (unsigned int)components.hour;
|
||||
zipInfo->tmz_date.tm_mday = (unsigned int)components.day;
|
||||
zipInfo->tmz_date.tm_mon = (unsigned int)components.month - 1;
|
||||
zipInfo->tmz_date.tm_year = (unsigned int)components.year;
|
||||
}
|
||||
|
||||
- (BOOL)writeFolderAtPath:(NSString *)path withFolderName:(NSString *)folderName withPassword:(NSString *)password
|
||||
{
|
||||
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
|
||||
|
||||
zip_fileinfo zipInfo = {{0}};
|
||||
|
||||
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
|
||||
if( attr )
|
||||
{
|
||||
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
|
||||
if( fileDate )
|
||||
{
|
||||
[self zipInfo:&zipInfo setDate: fileDate ];
|
||||
}
|
||||
|
||||
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
|
||||
// Get the permissions value from the files attributes
|
||||
NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];
|
||||
if (permissionsValue) {
|
||||
// Get the short value for the permissions
|
||||
short permissionsShort = permissionsValue.shortValue;
|
||||
|
||||
// Convert this into an octal by adding 010000, 010000 being the flag for a regular file
|
||||
NSInteger permissionsOctal = 0100000 + permissionsShort;
|
||||
|
||||
// Convert this into a long value
|
||||
uLong permissionsLong = @(permissionsOctal).unsignedLongValue;
|
||||
|
||||
// Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte
|
||||
zipInfo.external_fa = permissionsLong << 16L;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int len = 0;
|
||||
zipOpenNewFileInZip3(_zip, [[folderName stringByAppendingString:@"/"] UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_NO_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL,
|
||||
Z_DEFAULT_STRATEGY, [password UTF8String], 0);
|
||||
zipWriteInFileInZip(_zip, &len, 0);
|
||||
zipCloseFileInZip(_zip);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)writeFile:(NSString *)path withPassword:(NSString *)password;
|
||||
{
|
||||
return [self writeFileAtPath:path withFileName:nil withPassword:password];
|
||||
}
|
||||
|
||||
// supports writing files with logical folder/directory structure
|
||||
// *path* is the absolute path of the file that will be compressed
|
||||
// *fileName* is the relative name of the file how it is stored within the zip e.g. /folder/subfolder/text1.txt
|
||||
- (BOOL)writeFileAtPath:(NSString *)path withFileName:(NSString *)fileName withPassword:(NSString *)password
|
||||
{
|
||||
NSAssert((_zip != NULL), @"Attempting to write to an archive which was never opened");
|
||||
|
||||
FILE *input = fopen([path UTF8String], "r");
|
||||
if (NULL == input) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
const char *afileName;
|
||||
if (!fileName) {
|
||||
afileName = [path.lastPathComponent UTF8String];
|
||||
}
|
||||
else {
|
||||
afileName = [fileName UTF8String];
|
||||
}
|
||||
|
||||
zip_fileinfo zipInfo = {{0}};
|
||||
|
||||
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:path error: nil];
|
||||
if( attr )
|
||||
{
|
||||
NSDate *fileDate = (NSDate *)attr[NSFileModificationDate];
|
||||
if( fileDate )
|
||||
{
|
||||
[self zipInfo:&zipInfo setDate: fileDate ];
|
||||
}
|
||||
|
||||
// Write permissions into the external attributes, for details on this see here: http://unix.stackexchange.com/a/14727
|
||||
// Get the permissions value from the files attributes
|
||||
NSNumber *permissionsValue = (NSNumber *)attr[NSFilePosixPermissions];
|
||||
if (permissionsValue) {
|
||||
// Get the short value for the permissions
|
||||
short permissionsShort = permissionsValue.shortValue;
|
||||
|
||||
// Convert this into an octal by adding 010000, 010000 being the flag for a regular file
|
||||
NSInteger permissionsOctal = 0100000 + permissionsShort;
|
||||
|
||||
// Convert this into a long value
|
||||
uLong permissionsLong = @(permissionsOctal).unsignedLongValue;
|
||||
|
||||
// Store this into the external file attributes once it has been shifted 16 places left to form part of the second from last byte
|
||||
zipInfo.external_fa = permissionsLong << 16L;
|
||||
}
|
||||
}
|
||||
|
||||
void *buffer = malloc(CHUNK);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
zipOpenNewFileInZip3(_zip, afileName, &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);
|
||||
unsigned int len = 0;
|
||||
|
||||
while (!feof(input))
|
||||
{
|
||||
len = (unsigned int) fread(buffer, 1, CHUNK, input);
|
||||
zipWriteInFileInZip(_zip, buffer, len);
|
||||
}
|
||||
|
||||
zipCloseFileInZip(_zip);
|
||||
free(buffer);
|
||||
fclose(input);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)writeData:(NSData *)data filename:(NSString *)filename withPassword:(NSString *)password;
|
||||
{
|
||||
if (!_zip) {
|
||||
return NO;
|
||||
}
|
||||
if (!data) {
|
||||
return NO;
|
||||
}
|
||||
zip_fileinfo zipInfo = {{0,0,0,0,0,0},0,0,0};
|
||||
[self zipInfo:&zipInfo setDate:[NSDate date]];
|
||||
|
||||
zipOpenNewFileInZip3(_zip, [filename UTF8String], &zipInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, [password UTF8String], 0);
|
||||
|
||||
zipWriteInFileInZip(_zip, data.bytes, (unsigned int)data.length);
|
||||
|
||||
zipCloseFileInZip(_zip);
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)close
|
||||
{
|
||||
NSAssert((_zip != NULL), @"[SSZipArchive] Attempting to close an archive which was never opened");
|
||||
zipClose(_zip, NULL);
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - Private
|
||||
|
||||
// Format from http://newsgroups.derkeiler.com/Archive/Comp/comp.os.msdos.programmer/2009-04/msg00060.html
|
||||
// Two consecutive words, or a longword, YYYYYYYMMMMDDDDD hhhhhmmmmmmsssss
|
||||
// YYYYYYY is years from 1980 = 0
|
||||
// sssss is (seconds/2).
|
||||
//
|
||||
// 3658 = 0011 0110 0101 1000 = 0011011 0010 11000 = 27 2 24 = 2007-02-24
|
||||
// 7423 = 0111 0100 0010 0011 - 01110 100001 00011 = 14 33 3 = 14:33:06
|
||||
+ (NSDate *)_dateWithMSDOSFormat:(UInt32)msdosDateTime
|
||||
{
|
||||
static const UInt32 kYearMask = 0xFE000000;
|
||||
static const UInt32 kMonthMask = 0x1E00000;
|
||||
static const UInt32 kDayMask = 0x1F0000;
|
||||
static const UInt32 kHourMask = 0xF800;
|
||||
static const UInt32 kMinuteMask = 0x7E0;
|
||||
static const UInt32 kSecondMask = 0x1F;
|
||||
|
||||
static NSCalendar *gregorian;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
|
||||
gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
|
||||
#else
|
||||
gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
|
||||
#endif
|
||||
});
|
||||
|
||||
NSDateComponents *components = [[NSDateComponents alloc] init];
|
||||
|
||||
NSAssert(0xFFFFFFFF == (kYearMask | kMonthMask | kDayMask | kHourMask | kMinuteMask | kSecondMask), @"[SSZipArchive] MSDOS date masks don't add up");
|
||||
|
||||
[components setYear:1980 + ((msdosDateTime & kYearMask) >> 25)];
|
||||
[components setMonth:(msdosDateTime & kMonthMask) >> 21];
|
||||
[components setDay:(msdosDateTime & kDayMask) >> 16];
|
||||
[components setHour:(msdosDateTime & kHourMask) >> 11];
|
||||
[components setMinute:(msdosDateTime & kMinuteMask) >> 5];
|
||||
[components setSecond:(msdosDateTime & kSecondMask) * 2];
|
||||
|
||||
NSDate *date = [NSDate dateWithTimeInterval:0 sinceDate:[gregorian dateFromComponents:components]];
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[components release];
|
||||
#endif
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
@end
|
@@ -1,20 +0,0 @@
|
||||
//
|
||||
// ZipArchive.h
|
||||
// ZipArchive
|
||||
//
|
||||
// Created by Serhii Mumriak on 12/1/15.
|
||||
// Copyright © 2015 smumryak. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
//! Project version number for ZipArchive.
|
||||
FOUNDATION_EXPORT double ZipArchiveVersionNumber;
|
||||
|
||||
//! Project version string for ZipArchive.
|
||||
FOUNDATION_EXPORT const unsigned char ZipArchiveVersionString[];
|
||||
|
||||
// In this header, you should import all the public headers of your framework using statements like #import <ZipArchive/PublicHeader.h>
|
||||
|
||||
#import "SSZipArchive.h"
|
||||
|
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the definitions required to use AES in C. See aesopt.h
|
||||
for optimisation details.
|
||||
*/
|
||||
|
||||
#ifndef _AES_H
|
||||
#define _AES_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This include is used to find 8 & 32 bit unsigned integer types */
|
||||
#include "brg_types.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define AES_128 /* if a fast 128 bit key scheduler is needed */
|
||||
#define AES_192 /* if a fast 192 bit key scheduler is needed */
|
||||
#define AES_256 /* if a fast 256 bit key scheduler is needed */
|
||||
#define AES_VAR /* if variable key size scheduler is needed */
|
||||
#define AES_MODES /* if support is needed for modes */
|
||||
|
||||
/* The following must also be set in assembler files if being used */
|
||||
|
||||
#define AES_ENCRYPT /* if support for encryption is needed */
|
||||
#define AES_DECRYPT /* if support for decryption is needed */
|
||||
#define AES_REV_DKS /* define to reverse decryption key schedule */
|
||||
|
||||
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
|
||||
#define N_COLS 4 /* the number of columns in the state */
|
||||
|
||||
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
|
||||
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
|
||||
/* or 44, 52 or 60 32-bit words. */
|
||||
|
||||
#if defined( AES_VAR ) || defined( AES_256 )
|
||||
#define KS_LENGTH 60
|
||||
#elif defined( AES_192 )
|
||||
#define KS_LENGTH 52
|
||||
#else
|
||||
#define KS_LENGTH 44
|
||||
#endif
|
||||
|
||||
#define AES_RETURN INT_RETURN
|
||||
|
||||
/* the character array 'inf' in the following structures is used */
|
||||
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||
/* to hold the number of rounds multiplied by 16. The other three */
|
||||
/* elements can be used by code that implements additional modes */
|
||||
|
||||
typedef union
|
||||
{ uint_32t l;
|
||||
uint_8t b[4];
|
||||
} aes_inf;
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_encrypt_ctx;
|
||||
|
||||
typedef struct
|
||||
{ uint_32t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_decrypt_ctx;
|
||||
|
||||
/* This routine must be called before first use if non-static */
|
||||
/* tables are being used */
|
||||
|
||||
AES_RETURN aes_init(void);
|
||||
|
||||
/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
|
||||
/* those in the range 128 <= key_len <= 256 are given in bits */
|
||||
|
||||
#if defined( AES_ENCRYPT )
|
||||
|
||||
#if defined( AES_128 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_192 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_256 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DECRYPT )
|
||||
|
||||
#if defined( AES_128 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_192 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_256 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_MODES )
|
||||
|
||||
/* Multiple calls to the following subroutines for multiple block */
|
||||
/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
|
||||
/* long messages incremantally provided that the context AND the iv */
|
||||
/* are preserved between all such calls. For the ECB and CBC modes */
|
||||
/* each individual call within a series of incremental calls must */
|
||||
/* process only full blocks (i.e. len must be a multiple of 16) but */
|
||||
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
|
||||
/* calls of any length. Each mode is reset when a new AES key is */
|
||||
/* set but ECB and CBC operations can be reset without setting a */
|
||||
/* new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||
/* without setting the key, aes_mode_reset() must be called and the */
|
||||
/* IV must be set. NOTE: All these calls update the IV on exit so */
|
||||
/* this has to be reset if a new operation with the same IV as the */
|
||||
/* previous one is required (or decryption follows encryption with */
|
||||
/* the same IV array). */
|
||||
|
||||
AES_RETURN aes_test_alignment_detection(unsigned int n);
|
||||
|
||||
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#define aes_ofb_encrypt aes_ofb_crypt
|
||||
#define aes_ofb_decrypt aes_ofb_crypt
|
||||
|
||||
AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
typedef void cbuf_inc(unsigned char *cbuf);
|
||||
|
||||
#define aes_ctr_encrypt aes_ctr_crypt
|
||||
#define aes_ctr_decrypt aes_ctr_crypt
|
||||
|
||||
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,541 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef AES_VIA_ACE_H
|
||||
#define AES_VIA_ACE_H
|
||||
|
||||
#if defined( _MSC_VER )
|
||||
# define INLINE __inline
|
||||
#elif defined( __GNUC__ )
|
||||
# define INLINE static inline
|
||||
#else
|
||||
# error VIA ACE requires Microsoft or GNU C
|
||||
#endif
|
||||
|
||||
#define NEH_GENERATE 1
|
||||
#define NEH_LOAD 2
|
||||
#define NEH_HYBRID 3
|
||||
|
||||
#define MAX_READ_ATTEMPTS 1000
|
||||
|
||||
/* VIA Nehemiah RNG and ACE Feature Mask Values */
|
||||
|
||||
#define NEH_CPU_IS_VIA 0x00000001
|
||||
#define NEH_CPU_READ 0x00000010
|
||||
#define NEH_CPU_MASK 0x00000011
|
||||
|
||||
#define NEH_RNG_PRESENT 0x00000004
|
||||
#define NEH_RNG_ENABLED 0x00000008
|
||||
#define NEH_ACE_PRESENT 0x00000040
|
||||
#define NEH_ACE_ENABLED 0x00000080
|
||||
#define NEH_RNG_FLAGS (NEH_RNG_PRESENT | NEH_RNG_ENABLED)
|
||||
#define NEH_ACE_FLAGS (NEH_ACE_PRESENT | NEH_ACE_ENABLED)
|
||||
#define NEH_FLAGS_MASK (NEH_RNG_FLAGS | NEH_ACE_FLAGS)
|
||||
|
||||
/* VIA Nehemiah Advanced Cryptography Engine (ACE) Control Word Values */
|
||||
|
||||
#define NEH_GEN_KEY 0x00000000 /* generate key schedule */
|
||||
#define NEH_LOAD_KEY 0x00000080 /* load schedule from memory */
|
||||
#define NEH_ENCRYPT 0x00000000 /* encryption */
|
||||
#define NEH_DECRYPT 0x00000200 /* decryption */
|
||||
#define NEH_KEY128 0x00000000+0x0a /* 128 bit key */
|
||||
#define NEH_KEY192 0x00000400+0x0c /* 192 bit key */
|
||||
#define NEH_KEY256 0x00000800+0x0e /* 256 bit key */
|
||||
|
||||
#define NEH_ENC_GEN (NEH_ENCRYPT | NEH_GEN_KEY)
|
||||
#define NEH_DEC_GEN (NEH_DECRYPT | NEH_GEN_KEY)
|
||||
#define NEH_ENC_LOAD (NEH_ENCRYPT | NEH_LOAD_KEY)
|
||||
#define NEH_DEC_LOAD (NEH_DECRYPT | NEH_LOAD_KEY)
|
||||
|
||||
#define NEH_ENC_GEN_DATA {\
|
||||
NEH_ENC_GEN | NEH_KEY128, 0, 0, 0,\
|
||||
NEH_ENC_GEN | NEH_KEY192, 0, 0, 0,\
|
||||
NEH_ENC_GEN | NEH_KEY256, 0, 0, 0 }
|
||||
|
||||
#define NEH_ENC_LOAD_DATA {\
|
||||
NEH_ENC_LOAD | NEH_KEY128, 0, 0, 0,\
|
||||
NEH_ENC_LOAD | NEH_KEY192, 0, 0, 0,\
|
||||
NEH_ENC_LOAD | NEH_KEY256, 0, 0, 0 }
|
||||
|
||||
#define NEH_ENC_HYBRID_DATA {\
|
||||
NEH_ENC_GEN | NEH_KEY128, 0, 0, 0,\
|
||||
NEH_ENC_LOAD | NEH_KEY192, 0, 0, 0,\
|
||||
NEH_ENC_LOAD | NEH_KEY256, 0, 0, 0 }
|
||||
|
||||
#define NEH_DEC_GEN_DATA {\
|
||||
NEH_DEC_GEN | NEH_KEY128, 0, 0, 0,\
|
||||
NEH_DEC_GEN | NEH_KEY192, 0, 0, 0,\
|
||||
NEH_DEC_GEN | NEH_KEY256, 0, 0, 0 }
|
||||
|
||||
#define NEH_DEC_LOAD_DATA {\
|
||||
NEH_DEC_LOAD | NEH_KEY128, 0, 0, 0,\
|
||||
NEH_DEC_LOAD | NEH_KEY192, 0, 0, 0,\
|
||||
NEH_DEC_LOAD | NEH_KEY256, 0, 0, 0 }
|
||||
|
||||
#define NEH_DEC_HYBRID_DATA {\
|
||||
NEH_DEC_GEN | NEH_KEY128, 0, 0, 0,\
|
||||
NEH_DEC_LOAD | NEH_KEY192, 0, 0, 0,\
|
||||
NEH_DEC_LOAD | NEH_KEY256, 0, 0, 0 }
|
||||
|
||||
#define neh_enc_gen_key(x) ((x) == 128 ? (NEH_ENC_GEN | NEH_KEY128) : \
|
||||
(x) == 192 ? (NEH_ENC_GEN | NEH_KEY192) : (NEH_ENC_GEN | NEH_KEY256))
|
||||
|
||||
#define neh_enc_load_key(x) ((x) == 128 ? (NEH_ENC_LOAD | NEH_KEY128) : \
|
||||
(x) == 192 ? (NEH_ENC_LOAD | NEH_KEY192) : (NEH_ENC_LOAD | NEH_KEY256))
|
||||
|
||||
#define neh_enc_hybrid_key(x) ((x) == 128 ? (NEH_ENC_GEN | NEH_KEY128) : \
|
||||
(x) == 192 ? (NEH_ENC_LOAD | NEH_KEY192) : (NEH_ENC_LOAD | NEH_KEY256))
|
||||
|
||||
#define neh_dec_gen_key(x) ((x) == 128 ? (NEH_DEC_GEN | NEH_KEY128) : \
|
||||
(x) == 192 ? (NEH_DEC_GEN | NEH_KEY192) : (NEH_DEC_GEN | NEH_KEY256))
|
||||
|
||||
#define neh_dec_load_key(x) ((x) == 128 ? (NEH_DEC_LOAD | NEH_KEY128) : \
|
||||
(x) == 192 ? (NEH_DEC_LOAD | NEH_KEY192) : (NEH_DEC_LOAD | NEH_KEY256))
|
||||
|
||||
#define neh_dec_hybrid_key(x) ((x) == 128 ? (NEH_DEC_GEN | NEH_KEY128) : \
|
||||
(x) == 192 ? (NEH_DEC_LOAD | NEH_KEY192) : (NEH_DEC_LOAD | NEH_KEY256))
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 1200 )
|
||||
#define aligned_auto(type, name, no, stride) __declspec(align(stride)) type name[no]
|
||||
#else
|
||||
#define aligned_auto(type, name, no, stride) \
|
||||
unsigned char _##name[no * sizeof(type) + stride]; \
|
||||
type *name = (type*)(16 * ((((unsigned long)(_##name)) + stride - 1) / stride))
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 1200 )
|
||||
#define aligned_array(type, name, no, stride) __declspec(align(stride)) type name[no]
|
||||
#elif defined( __GNUC__ )
|
||||
#define aligned_array(type, name, no, stride) type name[no] __attribute__ ((aligned(stride)))
|
||||
#else
|
||||
#define aligned_array(type, name, no, stride) type name[no]
|
||||
#endif
|
||||
|
||||
/* VIA ACE codeword */
|
||||
|
||||
static unsigned char via_flags = 0;
|
||||
|
||||
#if defined ( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
|
||||
#define NEH_REKEY __asm pushfd __asm popfd
|
||||
#define NEH_AES __asm _emit 0xf3 __asm _emit 0x0f __asm _emit 0xa7
|
||||
#define NEH_ECB NEH_AES __asm _emit 0xc8
|
||||
#define NEH_CBC NEH_AES __asm _emit 0xd0
|
||||
#define NEH_CFB NEH_AES __asm _emit 0xe0
|
||||
#define NEH_OFB NEH_AES __asm _emit 0xe8
|
||||
#define NEH_RNG __asm _emit 0x0f __asm _emit 0xa7 __asm _emit 0xc0
|
||||
|
||||
INLINE int has_cpuid(void)
|
||||
{ char ret_value;
|
||||
__asm
|
||||
{ pushfd /* save EFLAGS register */
|
||||
mov eax,[esp] /* copy it to eax */
|
||||
mov edx,0x00200000 /* CPUID bit position */
|
||||
xor eax,edx /* toggle the CPUID bit */
|
||||
push eax /* attempt to set EFLAGS to */
|
||||
popfd /* the new value */
|
||||
pushfd /* get the new EFLAGS value */
|
||||
pop eax /* into eax */
|
||||
xor eax,[esp] /* xor with original value */
|
||||
and eax,edx /* has CPUID bit changed? */
|
||||
setne al /* set to 1 if we have been */
|
||||
mov ret_value,al /* able to change it */
|
||||
popfd /* restore original EFLAGS */
|
||||
}
|
||||
return (int)ret_value;
|
||||
}
|
||||
|
||||
INLINE int is_via_cpu(void)
|
||||
{ char ret_value;
|
||||
__asm
|
||||
{ push ebx
|
||||
xor eax,eax /* use CPUID to get vendor */
|
||||
cpuid /* identity string */
|
||||
xor eax,eax /* is it "CentaurHauls" ? */
|
||||
sub ebx,0x746e6543 /* 'Cent' */
|
||||
or eax,ebx
|
||||
sub edx,0x48727561 /* 'aurH' */
|
||||
or eax,edx
|
||||
sub ecx,0x736c7561 /* 'auls' */
|
||||
or eax,ecx
|
||||
sete al /* set to 1 if it is VIA ID */
|
||||
mov dl,NEH_CPU_READ /* mark CPU type as read */
|
||||
or dl,al /* & store result in flags */
|
||||
mov [via_flags],dl /* set VIA detected flag */
|
||||
mov ret_value,al /* able to change it */
|
||||
pop ebx
|
||||
}
|
||||
return (int)ret_value;
|
||||
}
|
||||
|
||||
INLINE int read_via_flags(void)
|
||||
{ char ret_value = 0;
|
||||
__asm
|
||||
{ mov eax,0xC0000000 /* Centaur extended CPUID */
|
||||
cpuid
|
||||
mov edx,0xc0000001 /* >= 0xc0000001 if support */
|
||||
cmp eax,edx /* for VIA extended feature */
|
||||
jnae no_rng /* flags is available */
|
||||
mov eax,edx /* read Centaur extended */
|
||||
cpuid /* feature flags */
|
||||
mov eax,NEH_FLAGS_MASK /* mask out and save */
|
||||
and eax,edx /* the RNG and ACE flags */
|
||||
or [via_flags],al /* present & enabled flags */
|
||||
mov ret_value,al /* able to change it */
|
||||
no_rng:
|
||||
}
|
||||
return (int)ret_value;
|
||||
}
|
||||
|
||||
INLINE unsigned int via_rng_in(void *buf)
|
||||
{ char ret_value = 0x1f;
|
||||
__asm
|
||||
{ push edi
|
||||
mov edi,buf /* input buffer address */
|
||||
xor edx,edx /* try to fetch 8 bytes */
|
||||
NEH_RNG /* do RNG read operation */
|
||||
and ret_value,al /* count of bytes returned */
|
||||
pop edi
|
||||
}
|
||||
return (int)ret_value;
|
||||
}
|
||||
|
||||
INLINE void via_ecb_op5(
|
||||
const void *k, const void *c, const void *s, void *d, int l)
|
||||
{ __asm
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
mov esi, (s)
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
NEH_ECB
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cbc_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{ __asm
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
mov esi, (s)
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_CBC
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cbc_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{ __asm
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
mov esi, (s)
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_CBC
|
||||
mov esi, eax
|
||||
mov edi, (w)
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cfb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{ __asm
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
mov esi, (s)
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_CFB
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_cfb_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{ __asm
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
mov esi, (s)
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_CFB
|
||||
mov esi, eax
|
||||
mov edi, (w)
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
movsd
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
INLINE void via_ofb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{ __asm
|
||||
{ push ebx
|
||||
NEH_REKEY
|
||||
mov ebx, (k)
|
||||
mov edx, (c)
|
||||
mov esi, (s)
|
||||
mov edi, (d)
|
||||
mov ecx, (l)
|
||||
mov eax, (v)
|
||||
NEH_OFB
|
||||
pop ebx
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined( __GNUC__ )
|
||||
|
||||
#define NEH_REKEY asm("pushfl\n popfl\n\t")
|
||||
#define NEH_ECB asm(".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t")
|
||||
#define NEH_CBC asm(".byte 0xf3, 0x0f, 0xa7, 0xd0\n\t")
|
||||
#define NEH_CFB asm(".byte 0xf3, 0x0f, 0xa7, 0xe0\n\t")
|
||||
#define NEH_OFB asm(".byte 0xf3, 0x0f, 0xa7, 0xe8\n\t")
|
||||
#define NEH_RNG asm(".byte 0x0f, 0xa7, 0xc0\n\t");
|
||||
|
||||
INLINE int has_cpuid(void)
|
||||
{ int val;
|
||||
asm("pushfl\n\t");
|
||||
asm("movl 0(%esp),%eax\n\t");
|
||||
asm("xor $0x00200000,%eax\n\t");
|
||||
asm("pushl %eax\n\t");
|
||||
asm("popfl\n\t");
|
||||
asm("pushfl\n\t");
|
||||
asm("popl %eax\n\t");
|
||||
asm("xorl 0(%esp),%edx\n\t");
|
||||
asm("andl $0x00200000,%eax\n\t");
|
||||
asm("movl %%eax,%0\n\t" : "=m" (val));
|
||||
asm("popfl\n\t");
|
||||
return val ? 1 : 0;
|
||||
}
|
||||
|
||||
INLINE int is_via_cpu(void)
|
||||
{ int val;
|
||||
asm("pushl %ebx\n\t");
|
||||
asm("xorl %eax,%eax\n\t");
|
||||
asm("cpuid\n\t");
|
||||
asm("xorl %eax,%eax\n\t");
|
||||
asm("subl $0x746e6543,%ebx\n\t");
|
||||
asm("orl %ebx,%eax\n\t");
|
||||
asm("subl $0x48727561,%edx\n\t");
|
||||
asm("orl %edx,%eax\n\t");
|
||||
asm("subl $0x736c7561,%ecx\n\t");
|
||||
asm("orl %ecx,%eax\n\t");
|
||||
asm("movl %%eax,%0\n\t" : "=m" (val));
|
||||
asm("popl %ebx\n\t");
|
||||
val = (val ? 0 : 1);
|
||||
via_flags = (val | NEH_CPU_READ);
|
||||
return val;
|
||||
}
|
||||
|
||||
INLINE int read_via_flags(void)
|
||||
{ unsigned char val;
|
||||
asm("movl $0xc0000000,%eax\n\t");
|
||||
asm("cpuid\n\t");
|
||||
asm("movl $0xc0000001,%edx\n\t");
|
||||
asm("cmpl %edx,%eax\n\t");
|
||||
asm("setae %al\n\t");
|
||||
asm("movb %%al,%0\n\t" : "=m" (val));
|
||||
if(!val) return 0;
|
||||
asm("movl $0xc0000001,%eax\n\t");
|
||||
asm("cpuid\n\t");
|
||||
asm("movb %%dl,%0\n\t" : "=m" (val));
|
||||
val &= NEH_FLAGS_MASK;
|
||||
via_flags |= val;
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
INLINE int via_rng_in(void *buf)
|
||||
{ int val;
|
||||
asm("pushl %edi\n\t");
|
||||
asm("movl %0,%%edi\n\t" : : "m" (buf));
|
||||
asm("xorl %edx,%edx\n\t");
|
||||
NEH_RNG
|
||||
asm("andl $0x0000001f,%eax\n\t");
|
||||
asm("movl %%eax,%0\n\t" : "=m" (val));
|
||||
asm("popl %edi\n\t");
|
||||
return val;
|
||||
}
|
||||
|
||||
INLINE volatile void via_ecb_op5(
|
||||
const void *k, const void *c, const void *s, void *d, int l)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
asm("movl %0, %%esi\n\t" : : "m" (s));
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
NEH_ECB;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cbc_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
asm("movl %0, %%esi\n\t" : : "m" (s));
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_CBC;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cbc_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
asm("movl %0, %%esi\n\t" : : "m" (s));
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_CBC;
|
||||
asm("movl %eax,%esi\n\t");
|
||||
asm("movl %0, %%edi\n\t" : : "m" (w));
|
||||
asm("movsl; movsl; movsl; movsl\n\t");
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cfb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
asm("movl %0, %%esi\n\t" : : "m" (s));
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_CFB;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_cfb_op7(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v, void *w)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
asm("movl %0, %%esi\n\t" : : "m" (s));
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_CFB;
|
||||
asm("movl %eax,%esi\n\t");
|
||||
asm("movl %0, %%edi\n\t" : : "m" (w));
|
||||
asm("movsl; movsl; movsl; movsl\n\t");
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
INLINE volatile void via_ofb_op6(
|
||||
const void *k, const void *c, const void *s, void *d, int l, void *v)
|
||||
{
|
||||
asm("pushl %ebx\n\t");
|
||||
NEH_REKEY;
|
||||
asm("movl %0, %%ebx\n\t" : : "m" (k));
|
||||
asm("movl %0, %%edx\n\t" : : "m" (c));
|
||||
asm("movl %0, %%esi\n\t" : : "m" (s));
|
||||
asm("movl %0, %%edi\n\t" : : "m" (d));
|
||||
asm("movl %0, %%ecx\n\t" : : "m" (l));
|
||||
asm("movl %0, %%eax\n\t" : : "m" (v));
|
||||
NEH_OFB;
|
||||
asm("popl %ebx\n\t");
|
||||
}
|
||||
|
||||
#else
|
||||
#error VIA ACE is not available with this compiler
|
||||
#endif
|
||||
|
||||
INLINE int via_ace_test(void)
|
||||
{
|
||||
return has_cpuid() && is_via_cpu() && ((read_via_flags() & NEH_ACE_FLAGS) == NEH_ACE_FLAGS);
|
||||
}
|
||||
|
||||
#define VIA_ACE_AVAILABLE (((via_flags & NEH_ACE_FLAGS) == NEH_ACE_FLAGS) \
|
||||
|| (via_flags & NEH_CPU_READ) && (via_flags & NEH_CPU_IS_VIA) || via_ace_test())
|
||||
|
||||
INLINE int via_rng_test(void)
|
||||
{
|
||||
return has_cpuid() && is_via_cpu() && ((read_via_flags() & NEH_RNG_FLAGS) == NEH_RNG_FLAGS);
|
||||
}
|
||||
|
||||
#define VIA_RNG_AVAILABLE (((via_flags & NEH_RNG_FLAGS) == NEH_RNG_FLAGS) \
|
||||
|| (via_flags & NEH_CPU_READ) && (via_flags & NEH_CPU_IS_VIA) || via_rng_test())
|
||||
|
||||
INLINE int read_via_rng(void *buf, int count)
|
||||
{ int nbr, max_reads, lcnt = count;
|
||||
unsigned char *p, *q;
|
||||
aligned_auto(unsigned char, bp, 64, 16);
|
||||
|
||||
if(!VIA_RNG_AVAILABLE)
|
||||
return 0;
|
||||
|
||||
do
|
||||
{
|
||||
max_reads = MAX_READ_ATTEMPTS;
|
||||
do
|
||||
nbr = via_rng_in(bp);
|
||||
while
|
||||
(nbr == 0 && --max_reads);
|
||||
|
||||
lcnt -= nbr;
|
||||
p = (unsigned char*)buf; q = bp;
|
||||
while(nbr--)
|
||||
*p++ = *q++;
|
||||
}
|
||||
while
|
||||
(lcnt && max_reads);
|
||||
|
||||
return count - lcnt;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,294 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
|
||||
#define so(y,x,c) word_out(y, c, s(x,c))
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define locals(y,x) x[4],y[4]
|
||||
#else
|
||||
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
|
||||
#endif
|
||||
|
||||
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||
s(y,2) = s(x,2); s(y,3) = s(x,3);
|
||||
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
||||
|
||||
#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||
#pragma optimize( "s", on )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
Yellin for this construction)
|
||||
*/
|
||||
|
||||
#define fwd_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
|
||||
|
||||
#if defined(FT4_SET)
|
||||
#undef dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
|
||||
#elif defined(FT1_SET)
|
||||
#undef dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
|
||||
#else
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
|
||||
#endif
|
||||
|
||||
#if defined(FL4_SET)
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
|
||||
#elif defined(FL1_SET)
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
|
||||
#else
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||
{ uint_32t locals(b0, b1);
|
||||
const uint_32t *kp;
|
||||
#if defined( dec_fmvars )
|
||||
dec_fmvars; /* declare variables for fwd_mcol() if needed */
|
||||
#endif
|
||||
|
||||
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
|
||||
return EXIT_FAILURE;
|
||||
|
||||
kp = cx->ks;
|
||||
state_in(b0, in, kp);
|
||||
|
||||
#if (ENC_UNROLL == FULL)
|
||||
|
||||
switch(cx->inf.b[0])
|
||||
{
|
||||
case 14 * 16:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 12 * 16:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 10 * 16:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
|
||||
round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (ENC_UNROLL == PARTIAL)
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b0, b1, kp);
|
||||
}
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp += N_COLS;
|
||||
round(fwd_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out, b0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ( FUNCS_IN_C & DECRYPTION_IN_C)
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||
#pragma optimize( "t", on )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
Yellin for this construction)
|
||||
*/
|
||||
|
||||
#define inv_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
|
||||
|
||||
#if defined(IT4_SET)
|
||||
#undef dec_imvars
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
|
||||
#elif defined(IT1_SET)
|
||||
#undef dec_imvars
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
|
||||
#else
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
|
||||
#endif
|
||||
|
||||
#if defined(IL4_SET)
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
|
||||
#elif defined(IL1_SET)
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
|
||||
#else
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
|
||||
#endif
|
||||
|
||||
/* This code can work with the decryption key schedule in the */
|
||||
/* order that is used for encrytpion (where the 1st decryption */
|
||||
/* round key is at the high end ot the schedule) or with a key */
|
||||
/* schedule that has been reversed to put the 1st decryption */
|
||||
/* round key at the low end of the schedule in memory (when */
|
||||
/* AES_REV_DKS is defined) */
|
||||
|
||||
#ifdef AES_REV_DKS
|
||||
#define key_ofs 0
|
||||
#define rnd_key(n) (kp + n * N_COLS)
|
||||
#else
|
||||
#define key_ofs 1
|
||||
#define rnd_key(n) (kp - n * N_COLS)
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||
{ uint_32t locals(b0, b1);
|
||||
#if defined( dec_imvars )
|
||||
dec_imvars; /* declare variables for inv_mcol() if needed */
|
||||
#endif
|
||||
const uint_32t *kp;
|
||||
|
||||
if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
|
||||
return EXIT_FAILURE;
|
||||
|
||||
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
|
||||
state_in(b0, in, kp);
|
||||
|
||||
#if (DEC_UNROLL == FULL)
|
||||
|
||||
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
|
||||
switch(cx->inf.b[0])
|
||||
{
|
||||
case 14 * 16:
|
||||
round(inv_rnd, b1, b0, rnd_key(-13));
|
||||
round(inv_rnd, b0, b1, rnd_key(-12));
|
||||
case 12 * 16:
|
||||
round(inv_rnd, b1, b0, rnd_key(-11));
|
||||
round(inv_rnd, b0, b1, rnd_key(-10));
|
||||
case 10 * 16:
|
||||
round(inv_rnd, b1, b0, rnd_key(-9));
|
||||
round(inv_rnd, b0, b1, rnd_key(-8));
|
||||
round(inv_rnd, b1, b0, rnd_key(-7));
|
||||
round(inv_rnd, b0, b1, rnd_key(-6));
|
||||
round(inv_rnd, b1, b0, rnd_key(-5));
|
||||
round(inv_rnd, b0, b1, rnd_key(-4));
|
||||
round(inv_rnd, b1, b0, rnd_key(-3));
|
||||
round(inv_rnd, b0, b1, rnd_key(-2));
|
||||
round(inv_rnd, b1, b0, rnd_key(-1));
|
||||
round(inv_lrnd, b0, b1, rnd_key( 0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (DEC_UNROLL == PARTIAL)
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b0, b1, kp);
|
||||
}
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ uint_32t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp = rnd_key(1);
|
||||
round(inv_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out, b0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
@@ -1,548 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.h"
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
# include "aes_via_ace.h"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialise the key schedule from the user supplied key. The key
|
||||
length can be specified in bytes, with legal values of 16, 24
|
||||
and 32, or in bits, with legal values of 128, 192 and 256. These
|
||||
values correspond with Nk values of 4, 6 and 8 respectively.
|
||||
|
||||
The following macros implement a single cycle in the key
|
||||
schedule generation process. The number of cycles needed
|
||||
for each cx->n_col and nk value is:
|
||||
|
||||
nk = 4 5 6 7 8
|
||||
------------------------------
|
||||
cx->n_col = 4 10 9 8 7 7
|
||||
cx->n_col = 5 14 11 10 9 9
|
||||
cx->n_col = 6 19 15 12 11 11
|
||||
cx->n_col = 7 21 19 16 13 14
|
||||
cx->n_col = 8 29 23 19 17 14
|
||||
*/
|
||||
|
||||
#if defined( REDUCE_CODE_SIZE )
|
||||
# define ls_box ls_sub
|
||||
uint_32t ls_sub(const uint_32t t, const uint_32t n);
|
||||
# define inv_mcol im_sub
|
||||
uint_32t im_sub(const uint_32t x);
|
||||
# ifdef ENC_KS_UNROLL
|
||||
# undef ENC_KS_UNROLL
|
||||
# endif
|
||||
# ifdef DEC_KS_UNROLL
|
||||
# undef DEC_KS_UNROLL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (FUNCS_IN_C & ENC_KEYING_IN_C)
|
||||
|
||||
#if defined(AES_128) || defined( AES_VAR )
|
||||
|
||||
#define ke4(k,i) \
|
||||
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||
k[4*(i)+6] = ss[2] ^= ss[1]; \
|
||||
k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint_32t ss[4];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef ENC_KS_UNROLL
|
||||
ke4(cx->ks, 0); ke4(cx->ks, 1);
|
||||
ke4(cx->ks, 2); ke4(cx->ks, 3);
|
||||
ke4(cx->ks, 4); ke4(cx->ks, 5);
|
||||
ke4(cx->ks, 6); ke4(cx->ks, 7);
|
||||
ke4(cx->ks, 8);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
for(i = 0; i < 9; ++i)
|
||||
ke4(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
ke4(cx->ks, 9);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined( AES_VAR )
|
||||
|
||||
#define kef6(k,i) \
|
||||
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||
k[6*(i)+ 8] = ss[2] ^= ss[1]; \
|
||||
k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke6(k,i) \
|
||||
{ kef6(k,i); \
|
||||
k[6*(i)+10] = ss[4] ^= ss[3]; \
|
||||
k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint_32t ss[6];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||
|
||||
#ifdef ENC_KS_UNROLL
|
||||
ke6(cx->ks, 0); ke6(cx->ks, 1);
|
||||
ke6(cx->ks, 2); ke6(cx->ks, 3);
|
||||
ke6(cx->ks, 4); ke6(cx->ks, 5);
|
||||
ke6(cx->ks, 6);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
for(i = 0; i < 7; ++i)
|
||||
ke6(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef6(cx->ks, 7);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined( AES_VAR )
|
||||
|
||||
#define kef8(k,i) \
|
||||
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||
k[8*(i)+10] = ss[2] ^= ss[1]; \
|
||||
k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke8(k,i) \
|
||||
{ kef8(k,i); \
|
||||
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
|
||||
k[8*(i)+13] = ss[5] ^= ss[4]; \
|
||||
k[8*(i)+14] = ss[6] ^= ss[5]; \
|
||||
k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint_32t ss[8];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||
cx->ks[6] = ss[6] = word_in(key, 6);
|
||||
cx->ks[7] = ss[7] = word_in(key, 7);
|
||||
|
||||
#ifdef ENC_KS_UNROLL
|
||||
ke8(cx->ks, 0); ke8(cx->ks, 1);
|
||||
ke8(cx->ks, 2); ke8(cx->ks, 3);
|
||||
ke8(cx->ks, 4); ke8(cx->ks, 5);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
for(i = 0; i < 6; ++i)
|
||||
ke8(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef8(cx->ks, 6);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_encrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_encrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_encrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||
|
||||
/* this is used to store the decryption round keys */
|
||||
/* in forward or reverse order */
|
||||
|
||||
#ifdef AES_REV_DKS
|
||||
#define v(n,i) ((n) - (i) + 2 * ((i) & 3))
|
||||
#else
|
||||
#define v(n,i) (i)
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES
|
||||
#define ff(x) (x)
|
||||
#else
|
||||
#define ff(x) inv_mcol(x)
|
||||
#if defined( dec_imvars )
|
||||
#define d_vars dec_imvars
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(AES_128) || defined( AES_VAR )
|
||||
|
||||
#define k4e(k,i) \
|
||||
{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
|
||||
k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
|
||||
k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
|
||||
ss[1] = ss[1] ^ ss[3]; \
|
||||
ss[2] = ss[2] ^ ss[3]; \
|
||||
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||
ss[i % 4] ^= ss[4]; \
|
||||
ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
|
||||
ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
|
||||
ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
|
||||
ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
|
||||
}
|
||||
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||
ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
|
||||
k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||
k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
|
||||
k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
|
||||
k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
|
||||
}
|
||||
|
||||
#define kdl4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
|
||||
k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
|
||||
k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
|
||||
k[v(40,(4*(i))+6)] = ss[0]; \
|
||||
k[v(40,(4*(i))+7)] = ss[1]; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
|
||||
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
|
||||
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
|
||||
}
|
||||
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
|
||||
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
|
||||
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
|
||||
}
|
||||
|
||||
#define kdl4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
|
||||
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
|
||||
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint_32t ss[5];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
kdf4(cx->ks, 0); kd4(cx->ks, 1);
|
||||
kd4(cx->ks, 2); kd4(cx->ks, 3);
|
||||
kd4(cx->ks, 4); kd4(cx->ks, 5);
|
||||
kd4(cx->ks, 6); kd4(cx->ks, 7);
|
||||
kd4(cx->ks, 8); kdl4(cx->ks, 9);
|
||||
#else
|
||||
{ uint_32t i;
|
||||
for(i = 0; i < 10; ++i)
|
||||
k4e(cx->ks, i);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 10 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined( AES_VAR )
|
||||
|
||||
#define k6ef(k,i) \
|
||||
{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
|
||||
k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
|
||||
k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define k6e(k,i) \
|
||||
{ k6ef(k,i); \
|
||||
k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
|
||||
k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
|
||||
#define kdf6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
|
||||
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
|
||||
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
|
||||
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
|
||||
}
|
||||
|
||||
#define kd6(k,i) \
|
||||
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
|
||||
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
|
||||
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
|
||||
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
|
||||
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
|
||||
}
|
||||
|
||||
#define kdl6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
|
||||
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint_32t ss[7];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
kdf6(cx->ks, 0); kd6(cx->ks, 1);
|
||||
kd6(cx->ks, 2); kd6(cx->ks, 3);
|
||||
kd6(cx->ks, 4); kd6(cx->ks, 5);
|
||||
kd6(cx->ks, 6); kdl6(cx->ks, 7);
|
||||
#else
|
||||
cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
|
||||
cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
|
||||
{ uint_32t i;
|
||||
|
||||
for(i = 0; i < 7; ++i)
|
||||
k6e(cx->ks, i);
|
||||
k6ef(cx->ks, 7);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 12 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined( AES_VAR )
|
||||
|
||||
#define k8ef(k,i) \
|
||||
{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
|
||||
k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
|
||||
k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define k8e(k,i) \
|
||||
{ k8ef(k,i); \
|
||||
k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
|
||||
k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
|
||||
k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
|
||||
k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
|
||||
#define kdf8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
|
||||
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
|
||||
ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
|
||||
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
|
||||
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
|
||||
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
|
||||
}
|
||||
|
||||
#define kd8(k,i) \
|
||||
{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
|
||||
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
|
||||
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
|
||||
ss[8] = ls_box(ss[3],0); \
|
||||
ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
|
||||
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
|
||||
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
|
||||
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
|
||||
}
|
||||
|
||||
#define kdl8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
|
||||
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint_32t ss[9];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
|
||||
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
|
||||
kdf8(cx->ks, 0); kd8(cx->ks, 1);
|
||||
kd8(cx->ks, 2); kd8(cx->ks, 3);
|
||||
kd8(cx->ks, 4); kd8(cx->ks, 5);
|
||||
kdl8(cx->ks, 6);
|
||||
#else
|
||||
cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
|
||||
cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
|
||||
cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
|
||||
cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
|
||||
{ uint_32t i;
|
||||
|
||||
for(i = 0; i < 6; ++i)
|
||||
k8e(cx->ks, i);
|
||||
k8ef(cx->ks, 6);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 14 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_decrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_decrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_decrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
@@ -1,739 +0,0 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the compilation options for AES (Rijndael) and code
|
||||
that is common across encryption, key scheduling and table generation.
|
||||
|
||||
OPERATION
|
||||
|
||||
These source code files implement the AES algorithm Rijndael designed by
|
||||
Joan Daemen and Vincent Rijmen. This version is designed for the standard
|
||||
block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
|
||||
and 32 bytes).
|
||||
|
||||
This version is designed for flexibility and speed using operations on
|
||||
32-bit words rather than operations on bytes. It can be compiled with
|
||||
either big or little endian internal byte order but is faster when the
|
||||
native byte order for the processor is used.
|
||||
|
||||
THE CIPHER INTERFACE
|
||||
|
||||
The cipher interface is implemented as an array of bytes in which lower
|
||||
AES bit sequence indexes map to higher numeric significance within bytes.
|
||||
|
||||
uint_8t (an unsigned 8-bit type)
|
||||
uint_32t (an unsigned 32-bit type)
|
||||
struct aes_encrypt_ctx (structure for the cipher encryption context)
|
||||
struct aes_decrypt_ctx (structure for the cipher decryption context)
|
||||
AES_RETURN the function return type
|
||||
|
||||
C subroutine calls:
|
||||
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_decrypt_ctx cx[1]);
|
||||
|
||||
IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
|
||||
you call aes_init() before AES is used so that the tables are initialised.
|
||||
|
||||
C++ aes class subroutines:
|
||||
|
||||
Class AESencrypt for encryption
|
||||
|
||||
Construtors:
|
||||
AESencrypt(void)
|
||||
AESencrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
AES_RETURN key128(const unsigned char *key)
|
||||
AES_RETURN key192(const unsigned char *key)
|
||||
AES_RETURN key256(const unsigned char *key)
|
||||
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
|
||||
|
||||
Class AESdecrypt for encryption
|
||||
Construtors:
|
||||
AESdecrypt(void)
|
||||
AESdecrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
AES_RETURN key128(const unsigned char *key)
|
||||
AES_RETURN key192(const unsigned char *key)
|
||||
AES_RETURN key256(const unsigned char *key)
|
||||
AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
|
||||
*/
|
||||
|
||||
#if !defined( _AESOPT_H )
|
||||
#define _AESOPT_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
#include "aescpp.h"
|
||||
#else
|
||||
#include "aes.h"
|
||||
#endif
|
||||
|
||||
/* PLATFORM SPECIFIC INCLUDES */
|
||||
|
||||
#include "brg_endian.h"
|
||||
|
||||
/* CONFIGURATION - THE USE OF DEFINES
|
||||
|
||||
Later in this section there are a number of defines that control the
|
||||
operation of the code. In each section, the purpose of each define is
|
||||
explained so that the relevant form can be included or excluded by
|
||||
setting either 1's or 0's respectively on the branches of the related
|
||||
#if clauses. The following local defines should not be changed.
|
||||
*/
|
||||
|
||||
#define ENCRYPTION_IN_C 1
|
||||
#define DECRYPTION_IN_C 2
|
||||
#define ENC_KEYING_IN_C 4
|
||||
#define DEC_KEYING_IN_C 8
|
||||
|
||||
#define NO_TABLES 0
|
||||
#define ONE_TABLE 1
|
||||
#define FOUR_TABLES 4
|
||||
#define NONE 0
|
||||
#define PARTIAL 1
|
||||
#define FULL 2
|
||||
|
||||
/* --- START OF USER CONFIGURED OPTIONS --- */
|
||||
|
||||
/* 1. BYTE ORDER WITHIN 32 BIT WORDS
|
||||
|
||||
The fundamental data processing units in Rijndael are 8-bit bytes. The
|
||||
input, output and key input are all enumerated arrays of bytes in which
|
||||
bytes are numbered starting at zero and increasing to one less than the
|
||||
number of bytes in the array in question. This enumeration is only used
|
||||
for naming bytes and does not imply any adjacency or order relationship
|
||||
from one byte to another. When these inputs and outputs are considered
|
||||
as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
|
||||
byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
|
||||
In this implementation bits are numbered from 0 to 7 starting at the
|
||||
numerically least significant end of each byte (bit n represents 2^n).
|
||||
|
||||
However, Rijndael can be implemented more efficiently using 32-bit
|
||||
words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
|
||||
into word[n]. While in principle these bytes can be assembled into words
|
||||
in any positions, this implementation only supports the two formats in
|
||||
which bytes in adjacent positions within words also have adjacent byte
|
||||
numbers. This order is called big-endian if the lowest numbered bytes
|
||||
in words have the highest numeric significance and little-endian if the
|
||||
opposite applies.
|
||||
|
||||
This code can work in either order irrespective of the order used by the
|
||||
machine on which it runs. Normally the internal byte order will be set
|
||||
to the order of the processor on which the code is to be run but this
|
||||
define can be used to reverse this in special situations
|
||||
|
||||
WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
|
||||
This define will hence be redefined later (in section 4) if necessary
|
||||
*/
|
||||
|
||||
#if 1
|
||||
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||
#elif 0
|
||||
# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0
|
||||
# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# error The algorithm byte order is not defined
|
||||
#endif
|
||||
|
||||
/* 2. VIA ACE SUPPORT */
|
||||
|
||||
#if !defined(__APPLE__) && defined( __GNUC__ ) && defined( __i386__ ) \
|
||||
|| defined( _WIN32 ) && defined( _M_IX86 ) \
|
||||
&& !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
# define VIA_ACE_POSSIBLE
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the VIA ACE is required. This uses
|
||||
inline assembler instructions and is only implemented for the Microsoft,
|
||||
Intel and GCC compilers. If VIA ACE is known to be present, then defining
|
||||
ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
|
||||
code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
|
||||
it is detected (both present and enabled) but the normal AES code will
|
||||
also be present.
|
||||
|
||||
When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
|
||||
aligned; other input/output buffers do not need to be 16 byte aligned
|
||||
but there are very large performance gains if this can be arranged.
|
||||
VIA ACE also requires the decryption key schedule to be in reverse
|
||||
order (which later checks below ensure).
|
||||
*/
|
||||
|
||||
#if 1 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# define USE_VIA_ACE_IF_PRESENT
|
||||
#endif
|
||||
|
||||
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
|
||||
# define ASSUME_VIA_ACE_PRESENT
|
||||
# endif
|
||||
|
||||
/* 3. ASSEMBLER SUPPORT
|
||||
|
||||
This define (which can be on the command line) enables the use of the
|
||||
assembler code routines for encryption, decryption and key scheduling
|
||||
as follows:
|
||||
|
||||
ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||
encryption, decryption and key scheduling
|
||||
ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
|
||||
Change one 'if 0' below to 'if 1' to select the version or define
|
||||
as a compilation option.
|
||||
*/
|
||||
|
||||
#if 0 && !defined( ASM_X86_V1C )
|
||||
# define ASM_X86_V1C
|
||||
#elif 0 && !defined( ASM_X86_V2 )
|
||||
# define ASM_X86_V2
|
||||
#elif 0 && !defined( ASM_X86_V2C )
|
||||
# define ASM_X86_V2C
|
||||
#elif 0 && !defined( ASM_AMD64_C )
|
||||
# define ASM_AMD64_C
|
||||
#endif
|
||||
|
||||
#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
|
||||
&& !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )
|
||||
# error Assembler code is only available for x86 and AMD64 systems
|
||||
#endif
|
||||
|
||||
/* 4. FAST INPUT/OUTPUT OPERATIONS.
|
||||
|
||||
On some machines it is possible to improve speed by transferring the
|
||||
bytes in the input and output arrays to and from the internal 32-bit
|
||||
variables by addressing these arrays as if they are arrays of 32-bit
|
||||
words. On some machines this will always be possible but there may
|
||||
be a large performance penalty if the byte arrays are not aligned on
|
||||
the normal word boundaries. On other machines this technique will
|
||||
lead to memory access errors when such 32-bit word accesses are not
|
||||
properly aligned. The option SAFE_IO avoids such problems but will
|
||||
often be slower on those machines that support misaligned access
|
||||
(especially so if care is taken to align the input and output byte
|
||||
arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
|
||||
assumed that access to byte arrays as if they are arrays of 32-bit
|
||||
words will not cause problems when such accesses are misaligned.
|
||||
*/
|
||||
#if 1 && !defined( _MSC_VER )
|
||||
# define SAFE_IO
|
||||
#endif
|
||||
|
||||
/* 5. LOOP UNROLLING
|
||||
|
||||
The code for encryption and decrytpion cycles through a number of rounds
|
||||
that can be implemented either in a loop or by expanding the code into a
|
||||
long sequence of instructions, the latter producing a larger program but
|
||||
one that will often be much faster. The latter is called loop unrolling.
|
||||
There are also potential speed advantages in expanding two iterations in
|
||||
a loop with half the number of iterations, which is called partial loop
|
||||
unrolling. The following options allow partial or full loop unrolling
|
||||
to be set independently for encryption and decryption
|
||||
*/
|
||||
#if 1
|
||||
# define ENC_UNROLL FULL
|
||||
#elif 0
|
||||
# define ENC_UNROLL PARTIAL
|
||||
#else
|
||||
# define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define DEC_UNROLL FULL
|
||||
#elif 0
|
||||
# define DEC_UNROLL PARTIAL
|
||||
#else
|
||||
# define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define ENC_KS_UNROLL
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define DEC_KS_UNROLL
|
||||
#endif
|
||||
|
||||
/* 6. FAST FINITE FIELD OPERATIONS
|
||||
|
||||
If this section is included, tables are used to provide faster finite
|
||||
field arithmetic (this has no effect if FIXED_TABLES is defined).
|
||||
*/
|
||||
#if 1
|
||||
# define FF_TABLES
|
||||
#endif
|
||||
|
||||
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||
|
||||
The internal state of Rijndael is stored in a number of local 32-bit
|
||||
word varaibles which can be defined either as an array or as individual
|
||||
names variables. Include this section if you want to store these local
|
||||
varaibles in arrays. Otherwise individual local variables will be used.
|
||||
*/
|
||||
#if 1
|
||||
# define ARRAYS
|
||||
#endif
|
||||
|
||||
/* 8. FIXED OR DYNAMIC TABLES
|
||||
|
||||
When this section is included the tables used by the code are compiled
|
||||
statically into the binary file. Otherwise the subroutine aes_init()
|
||||
must be called to compute them before the code is first used.
|
||||
*/
|
||||
#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
# define FIXED_TABLES
|
||||
#endif
|
||||
|
||||
/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
|
||||
|
||||
In some systems it is better to mask longer values to extract bytes
|
||||
rather than using a cast. This option allows this choice.
|
||||
*/
|
||||
#if 0
|
||||
# define to_byte(x) ((uint_8t)(x))
|
||||
#else
|
||||
# define to_byte(x) ((x) & 0xff)
|
||||
#endif
|
||||
|
||||
/* 10. TABLE ALIGNMENT
|
||||
|
||||
On some sytsems speed will be improved by aligning the AES large lookup
|
||||
tables on particular boundaries. This define should be set to a power of
|
||||
two giving the desired alignment. It can be left undefined if alignment
|
||||
is not needed. This option is specific to the Microsft VC++ compiler -
|
||||
it seems to sometimes cause trouble for the VC++ version 6 compiler.
|
||||
*/
|
||||
|
||||
#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||
# define TABLE_ALIGN 32
|
||||
#endif
|
||||
|
||||
/* 11. REDUCE CODE AND TABLE SIZE
|
||||
|
||||
This replaces some expanded macros with function calls if AES_ASM_V2 or
|
||||
AES_ASM_V2C are defined
|
||||
*/
|
||||
|
||||
#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
|
||||
# define REDUCE_CODE_SIZE
|
||||
#endif
|
||||
|
||||
/* 12. TABLE OPTIONS
|
||||
|
||||
This cipher proceeds by repeating in a number of cycles known as 'rounds'
|
||||
which are implemented by a round function which can optionally be speeded
|
||||
up using tables. The basic tables are each 256 32-bit words, with either
|
||||
one or four tables being required for each round function depending on
|
||||
how much speed is required. The encryption and decryption round functions
|
||||
are different and the last encryption and decrytpion round functions are
|
||||
different again making four different round functions in all.
|
||||
|
||||
This means that:
|
||||
1. Normal encryption and decryption rounds can each use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
2. The last encryption and decryption rounds can also use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
|
||||
Include or exclude the appropriate definitions below to set the number
|
||||
of tables used by this implementation.
|
||||
*/
|
||||
|
||||
#if 1 /* set tables for the normal encryption round */
|
||||
# define ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last encryption round */
|
||||
# define LAST_ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define LAST_ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define LAST_ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the normal decryption round */
|
||||
# define DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last decryption round */
|
||||
# define LAST_DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define LAST_DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define LAST_DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
/* The decryption key schedule can be speeded up with tables in the same
|
||||
way that the round functions can. Include or exclude the following
|
||||
defines to set this requirement.
|
||||
*/
|
||||
#if 1
|
||||
# define KEY_SCHED FOUR_TABLES
|
||||
#elif 0
|
||||
# define KEY_SCHED ONE_TABLE
|
||||
#else
|
||||
# define KEY_SCHED NO_TABLES
|
||||
#endif
|
||||
|
||||
/* ---- END OF USER CONFIGURED OPTIONS ---- */
|
||||
|
||||
/* VIA ACE support is only available for VC++ and GCC */
|
||||
|
||||
#if !defined( _MSC_VER ) && !defined( __GNUC__ )
|
||||
# if defined( ASSUME_VIA_ACE_PRESENT )
|
||||
# undef ASSUME_VIA_ACE_PRESENT
|
||||
# endif
|
||||
# if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# undef USE_VIA_ACE_IF_PRESENT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# define USE_VIA_ACE_IF_PRESENT
|
||||
#endif
|
||||
|
||||
#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
|
||||
# define AES_REV_DKS
|
||||
#endif
|
||||
|
||||
/* Assembler support requires the use of platform byte order */
|
||||
|
||||
#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
|
||||
&& (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
|
||||
# undef ALGORITHM_BYTE_ORDER
|
||||
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||
#endif
|
||||
|
||||
/* In this implementation the columns of the state array are each held in
|
||||
32-bit words. The state array can be held in various ways: in an array
|
||||
of words, in a number of individual word variables or in a number of
|
||||
processor registers. The following define maps a variable name x and
|
||||
a column number c to the way the state array variable is to be held.
|
||||
The first define below maps the state into an array x[c] whereas the
|
||||
second form maps the state into a number of individual variables x0,
|
||||
x1, etc. Another form could map individual state colums to machine
|
||||
register names.
|
||||
*/
|
||||
|
||||
#if defined( ARRAYS )
|
||||
# define s(x,c) x[c]
|
||||
#else
|
||||
# define s(x,c) x##c
|
||||
#endif
|
||||
|
||||
/* This implementation provides subroutines for encryption, decryption
|
||||
and for setting the three key lengths (separately) for encryption
|
||||
and decryption. Since not all functions are needed, masks are set
|
||||
up here to determine which will be implemented in C
|
||||
*/
|
||||
|
||||
#if !defined( AES_ENCRYPT )
|
||||
# define EFUNCS_IN_C 0
|
||||
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|
||||
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||
# define EFUNCS_IN_C ENC_KEYING_IN_C
|
||||
#elif !defined( ASM_X86_V2 )
|
||||
# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
|
||||
#else
|
||||
# define EFUNCS_IN_C 0
|
||||
#endif
|
||||
|
||||
#if !defined( AES_DECRYPT )
|
||||
# define DFUNCS_IN_C 0
|
||||
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|
||||
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||
# define DFUNCS_IN_C DEC_KEYING_IN_C
|
||||
#elif !defined( ASM_X86_V2 )
|
||||
# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
|
||||
#else
|
||||
# define DFUNCS_IN_C 0
|
||||
#endif
|
||||
|
||||
#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C )
|
||||
|
||||
/* END OF CONFIGURATION OPTIONS */
|
||||
|
||||
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
|
||||
|
||||
/* Disable or report errors on some combinations of options */
|
||||
|
||||
#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
|
||||
# undef LAST_ENC_ROUND
|
||||
# define LAST_ENC_ROUND NO_TABLES
|
||||
#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
|
||||
# undef LAST_ENC_ROUND
|
||||
# define LAST_ENC_ROUND ONE_TABLE
|
||||
#endif
|
||||
|
||||
#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
|
||||
# undef ENC_UNROLL
|
||||
# define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
|
||||
# undef LAST_DEC_ROUND
|
||||
# define LAST_DEC_ROUND NO_TABLES
|
||||
#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
|
||||
# undef LAST_DEC_ROUND
|
||||
# define LAST_DEC_ROUND ONE_TABLE
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
|
||||
# undef DEC_UNROLL
|
||||
# define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if defined( bswap32 )
|
||||
# define aes_sw32 bswap32
|
||||
#elif defined( bswap_32 )
|
||||
# define aes_sw32 bswap_32
|
||||
#else
|
||||
# define brot(x,n) (((uint_32t)(x) << n) | ((uint_32t)(x) >> (32 - n)))
|
||||
# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
/* upr(x,n): rotates bytes within words by n positions, moving bytes to
|
||||
higher index positions with wrap around into low positions
|
||||
ups(x,n): moves bytes by n positions to higher index positions in
|
||||
words but without wrap around
|
||||
bval(x,n): extracts a byte from a word
|
||||
|
||||
WARNING: The definitions given here are intended only for use with
|
||||
unsigned variables and with shift counts that are compile
|
||||
time constants
|
||||
*/
|
||||
|
||||
#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
|
||||
# define upr(x,n) (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint_32t) (x) << (8 * (n)))
|
||||
# define bval(x,n) to_byte((x) >> (8 * (n)))
|
||||
# define bytes2word(b0, b1, b2, b3) \
|
||||
(((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))
|
||||
#endif
|
||||
|
||||
#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
|
||||
# define upr(x,n) (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint_32t) (x) >> (8 * (n)))
|
||||
# define bval(x,n) to_byte((x) >> (24 - 8 * (n)))
|
||||
# define bytes2word(b0, b1, b2, b3) \
|
||||
(((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))
|
||||
#endif
|
||||
|
||||
#if defined( SAFE_IO )
|
||||
# define word_in(x,c) bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \
|
||||
((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])
|
||||
# define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \
|
||||
((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }
|
||||
#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
|
||||
# define word_in(x,c) (*((uint_32t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))
|
||||
#else
|
||||
# define word_in(x,c) aes_sw32(*((uint_32t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))
|
||||
#endif
|
||||
|
||||
/* the finite field modular polynomial and elements */
|
||||
|
||||
#define WPOLY 0x011b
|
||||
#define BPOLY 0x1b
|
||||
|
||||
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
|
||||
|
||||
#define gf_c1 0x80808080
|
||||
#define gf_c2 0x7f7f7f7f
|
||||
#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
|
||||
|
||||
/* The following defines provide alternative definitions of gf_mulx that might
|
||||
give improved performance if a fast 32-bit multiply is not available. Note
|
||||
that a temporary variable u needs to be defined where gf_mulx is used.
|
||||
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||
#define gf_c4 (0x01010101 * BPOLY)
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
|
||||
*/
|
||||
|
||||
/* Work out which tables are needed for the different options */
|
||||
|
||||
#if defined( ASM_X86_V1C )
|
||||
# if defined( ENC_ROUND )
|
||||
# undef ENC_ROUND
|
||||
# endif
|
||||
# define ENC_ROUND FOUR_TABLES
|
||||
# if defined( LAST_ENC_ROUND )
|
||||
# undef LAST_ENC_ROUND
|
||||
# endif
|
||||
# define LAST_ENC_ROUND FOUR_TABLES
|
||||
# if defined( DEC_ROUND )
|
||||
# undef DEC_ROUND
|
||||
# endif
|
||||
# define DEC_ROUND FOUR_TABLES
|
||||
# if defined( LAST_DEC_ROUND )
|
||||
# undef LAST_DEC_ROUND
|
||||
# endif
|
||||
# define LAST_DEC_ROUND FOUR_TABLES
|
||||
# if defined( KEY_SCHED )
|
||||
# undef KEY_SCHED
|
||||
# define KEY_SCHED FOUR_TABLES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
|
||||
# if ENC_ROUND == ONE_TABLE
|
||||
# define FT1_SET
|
||||
# elif ENC_ROUND == FOUR_TABLES
|
||||
# define FT4_SET
|
||||
# else
|
||||
# define SBX_SET
|
||||
# endif
|
||||
# if LAST_ENC_ROUND == ONE_TABLE
|
||||
# define FL1_SET
|
||||
# elif LAST_ENC_ROUND == FOUR_TABLES
|
||||
# define FL4_SET
|
||||
# elif !defined( SBX_SET )
|
||||
# define SBX_SET
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
|
||||
# if DEC_ROUND == ONE_TABLE
|
||||
# define IT1_SET
|
||||
# elif DEC_ROUND == FOUR_TABLES
|
||||
# define IT4_SET
|
||||
# else
|
||||
# define ISB_SET
|
||||
# endif
|
||||
# if LAST_DEC_ROUND == ONE_TABLE
|
||||
# define IL1_SET
|
||||
# elif LAST_DEC_ROUND == FOUR_TABLES
|
||||
# define IL4_SET
|
||||
# elif !defined(ISB_SET)
|
||||
# define ISB_SET
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
|
||||
# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))
|
||||
# if KEY_SCHED == ONE_TABLE
|
||||
# if !defined( FL1_SET ) && !defined( FL4_SET )
|
||||
# define LS1_SET
|
||||
# endif
|
||||
# elif KEY_SCHED == FOUR_TABLES
|
||||
# if !defined( FL4_SET )
|
||||
# define LS4_SET
|
||||
# endif
|
||||
# elif !defined( SBX_SET )
|
||||
# define SBX_SET
|
||||
# endif
|
||||
# endif
|
||||
# if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||
# if KEY_SCHED == ONE_TABLE
|
||||
# define IM1_SET
|
||||
# elif KEY_SCHED == FOUR_TABLES
|
||||
# define IM4_SET
|
||||
# elif !defined( SBX_SET )
|
||||
# define SBX_SET
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* generic definitions of Rijndael macros that use tables */
|
||||
|
||||
#define no_table(x,box,vf,rf,c) bytes2word( \
|
||||
box[bval(vf(x,0,c),rf(0,c))], \
|
||||
box[bval(vf(x,1,c),rf(1,c))], \
|
||||
box[bval(vf(x,2,c),rf(2,c))], \
|
||||
box[bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
#define one_table(x,op,tab,vf,rf,c) \
|
||||
( tab[bval(vf(x,0,c),rf(0,c))] \
|
||||
^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
|
||||
^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
|
||||
^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
|
||||
|
||||
#define four_tables(x,tab,vf,rf,c) \
|
||||
( tab[0][bval(vf(x,0,c),rf(0,c))] \
|
||||
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
||||
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
||||
^ tab[3][bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
#define vf1(x,r,c) (x)
|
||||
#define rf1(r,c) (r)
|
||||
#define rf2(r,c) ((8+r-c)&3)
|
||||
|
||||
/* perform forward and inverse column mix operation on four bytes in long word x in */
|
||||
/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
|
||||
|
||||
#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
|
||||
|
||||
#if defined( FM4_SET ) /* not currently used */
|
||||
# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0)
|
||||
#elif defined( FM1_SET ) /* not currently used */
|
||||
# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
|
||||
#else
|
||||
# define dec_fmvars uint_32t g2
|
||||
# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
|
||||
#endif
|
||||
|
||||
#if defined( IM4_SET )
|
||||
# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
|
||||
#elif defined( IM1_SET )
|
||||
# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
|
||||
#else
|
||||
# define dec_imvars uint_32t g2, g4, g9
|
||||
# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
|
||||
(x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
|
||||
#endif
|
||||
|
||||
#if defined( FL4_SET )
|
||||
# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c)
|
||||
#elif defined( LS4_SET )
|
||||
# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c)
|
||||
#elif defined( FL1_SET )
|
||||
# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c)
|
||||
#elif defined( LS1_SET )
|
||||
# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c)
|
||||
#else
|
||||
# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
|
||||
# define ISB_SET
|
||||
#endif
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user