react-native-update 10.34.8 → 10.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ set(HDIFFPATCH_DIR ${ANDROID_JNI_DIR}/HDiffPatch)
7
7
  set(LZMA_DIR ${ANDROID_JNI_DIR}/lzma)
8
8
  set(HDP_SOURCES
9
9
  ${CMAKE_CURRENT_SOURCE_DIR}/pushy.c
10
- ${CMAKE_CURRENT_SOURCE_DIR}/hpatch.c
10
+ ${ANDROID_JNI_DIR}/hpatch.c
11
11
  ${HDIFFPATCH_DIR}/libHDiffPatch/HPatch/patch.c
12
12
  ${HDIFFPATCH_DIR}/file_for_patch.c
13
13
  ${LZMA_DIR}/C/LzmaDec.c
@@ -22,6 +22,7 @@ add_library(rnupdate SHARED
22
22
 
23
23
  target_include_directories(rnupdate PRIVATE
24
24
  ${CMAKE_CURRENT_SOURCE_DIR}
25
+ ${ANDROID_JNI_DIR}
25
26
  ${HDIFFPATCH_DIR}
26
27
  ${HDIFFPATCH_DIR}/libHDiffPatch/HPatch
27
28
  ${LZMA_DIR}/C
@@ -57,7 +57,7 @@ export class DownloadTask {
57
57
 
58
58
  try {
59
59
  try {
60
- const exists = fileIo.accessSync(params.targetFile);
60
+ let exists = fileIo.accessSync(params.targetFile);
61
61
  if (exists) {
62
62
  await fileIo.unlink(params.targetFile);
63
63
  } else {
@@ -65,7 +65,7 @@ export class DownloadTask {
65
65
  0,
66
66
  params.targetFile.lastIndexOf('/'),
67
67
  );
68
- const exists = fileIo.accessSync(targetDir);
68
+ exists = fileIo.accessSync(targetDir);
69
69
  if (!exists) {
70
70
  await fileIo.mkdir(targetDir);
71
71
  }
@@ -1,49 +1,41 @@
1
- import { HotReloadConfig, JSBundleProvider, JSBundleProviderError, JSPackagerClientConfig } from '@rnoh/react-native-openharmony';
2
- import fileIo from '@ohos.file.fs';
1
+ import {
2
+ FileJSBundle,
3
+ HotReloadConfig,
4
+ JSBundleProvider,
5
+ JSBundleProviderError
6
+ } from '@rnoh/react-native-openharmony';
3
7
  import common from '@ohos.app.ability.common';
8
+ import fs from '@ohos.file.fs';
4
9
  import { UpdateContext } from './UpdateContext';
5
10
 
6
11
  export class PushyFileJSBundleProvider extends JSBundleProvider {
7
12
  private updateContext: UpdateContext;
8
- private filePath: string = ''
13
+ private path: string = ''
9
14
 
10
15
  constructor(context: common.UIAbilityContext) {
11
16
  super();
12
17
  this.updateContext = new UpdateContext(context);
18
+ this.path = this.updateContext.getBundleUrl();
13
19
  }
20
+
14
21
  getURL(): string {
15
- return this.updateContext.getBundleUrl()?.substring(1);
22
+ return this.path;
16
23
  }
17
24
 
18
- async getBundle(): Promise<ArrayBuffer> {
25
+ async getBundle(): Promise<FileJSBundle> {
19
26
  try {
20
- this.filePath = this.updateContext.getBundleUrl();
21
- const res = fileIo.accessSync(this.filePath);
22
- if (res) {
23
- const file = fileIo.openSync(this.filePath, fileIo.OpenMode.READ_ONLY);
24
- try {
25
- const stat = await fileIo.stat(this.filePath);
26
- const fileSize = stat.size;
27
- const buffer = new ArrayBuffer(fileSize);
28
- const bytesRead = fileIo.readSync(file.fd, buffer, {
29
- offset: 0,
30
- length: fileSize
31
- });
32
-
33
- if (bytesRead !== fileSize) {
34
- throw new Error(`Failed to read entire file: read ${bytesRead} of ${fileSize} bytes`);
35
- }
36
- return buffer;
37
- } finally {
38
- fileIo.closeSync(file.fd);
27
+ const status = await fs.access(this.path, fs.OpenMode.READ_ONLY);
28
+ if (status) {
29
+ return {
30
+ filePath: this.path
39
31
  }
40
32
  }
41
33
  throw new Error('Update bundle not found');
42
34
  } catch (error) {
43
35
  throw new JSBundleProviderError({
44
- whatHappened: `Couldn't load JSBundle from ${this.filePath}`,
36
+ whatHappened: `Couldn't load JSBundle from ${this.path}`,
45
37
  extraData: error,
46
- howCanItBeFixed: [`Check if a bundle exists at "${this.filePath}" on your device.`]
38
+ howCanItBeFixed: [`Check if a bundle exists at "${this.path}" on your device.`]
47
39
  })
48
40
  }
49
41
  }
@@ -1,9 +1,10 @@
1
- import { TurboModule, TurboModuleContext } from '@rnoh/react-native-openharmony/ts';
1
+ import {
2
+ TurboModule,
3
+ TurboModuleContext,
4
+ } from '@rnoh/react-native-openharmony/ts';
2
5
  import common from '@ohos.app.ability.common';
3
6
  import dataPreferences from '@ohos.data.preferences';
4
7
  import { bundleManager } from '@kit.AbilityKit';
5
- import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
6
- import { BusinessError } from '@ohos.base';
7
8
  import logger from './Logger';
8
9
  import { UpdateModuleImpl } from './UpdateModuleImpl';
9
10
  import { UpdateContext } from './UpdateContext';
@@ -23,50 +24,60 @@ export class PushyTurboModule extends TurboModule {
23
24
  EventHub.getInstance().setRNInstance(ctx.rnInstance);
24
25
  }
25
26
 
26
-
27
- getConstants(): Object {
28
- logger.debug(TAG, ',call getConstants');
29
- const context = this.mUiCtx;
30
- const preferencesManager = dataPreferences.getPreferencesSync(context,{ name: 'update' });
31
- const isFirstTime = preferencesManager.getSync('isFirstTime', false) as boolean;
32
- const rolledBackVersion = preferencesManager.getSync('rolledBackVersion', '') as string;
33
- const uuid = preferencesManager.getSync('uuid', '') as string;
34
- const currentVersion = preferencesManager.getSync('currentVersion', '') as string;
35
- const currentVersionInfo = this.context.getKv(`hash_${currentVersion}`);
36
- const buildTime = preferencesManager.getSync('buildTime', '') as string;
37
- const isUsingBundleUrl = this.context.getIsUsingBundleUrl();
38
- let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
39
- let packageVersion = '';
40
- try {
41
- const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
42
- packageVersion = bundleInfo?.versionName || 'Unknown';
43
- } catch (error) {
44
- console.error('Failed to get bundle info:', error);
45
- }
46
-
47
- if (isFirstTime) {
48
- preferencesManager.deleteSync('isFirstTime');
49
- }
50
-
51
- if (rolledBackVersion) {
52
- preferencesManager.deleteSync('rolledBackVersion');
53
- }
54
-
55
- return {
56
- downloadRootDir: `${context.filesDir}/_update`,
57
- currentVersionInfo,
58
- packageVersion,
59
- currentVersion,
60
- buildTime,
61
- isUsingBundleUrl,
62
- isFirstTime,
63
- rolledBackVersion,
64
- uuid,
65
- };
66
- }
67
-
68
-
69
- setLocalHashInfo(hash: string, info: string): boolean {
27
+ getConstants(): Object {
28
+ logger.debug(TAG, ',call getConstants');
29
+ const context = this.mUiCtx;
30
+ const preferencesManager = dataPreferences.getPreferencesSync(context, {
31
+ name: 'update',
32
+ });
33
+ const isFirstTime = preferencesManager.getSync(
34
+ 'isFirstTime',
35
+ false,
36
+ ) as boolean;
37
+ const rolledBackVersion = preferencesManager.getSync(
38
+ 'rolledBackVersion',
39
+ '',
40
+ ) as string;
41
+ const uuid = preferencesManager.getSync('uuid', '') as string;
42
+ const currentVersion = preferencesManager.getSync(
43
+ 'currentVersion',
44
+ '',
45
+ ) as string;
46
+ const currentVersionInfo = this.context.getKv(`hash_${currentVersion}`);
47
+ const buildTime = preferencesManager.getSync('buildTime', '') as string;
48
+ const isUsingBundleUrl = this.context.getIsUsingBundleUrl();
49
+ let bundleFlags =
50
+ bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION;
51
+ let packageVersion = '';
52
+ try {
53
+ const bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags);
54
+ packageVersion = bundleInfo?.versionName || 'Unknown';
55
+ } catch (error) {
56
+ console.error('Failed to get bundle info:', error);
57
+ }
58
+
59
+ if (isFirstTime) {
60
+ preferencesManager.deleteSync('isFirstTime');
61
+ }
62
+
63
+ if (rolledBackVersion) {
64
+ preferencesManager.deleteSync('rolledBackVersion');
65
+ }
66
+
67
+ return {
68
+ downloadRootDir: `${context.filesDir}/_update`,
69
+ currentVersionInfo,
70
+ packageVersion,
71
+ currentVersion,
72
+ buildTime,
73
+ isUsingBundleUrl,
74
+ isFirstTime,
75
+ rolledBackVersion,
76
+ uuid,
77
+ };
78
+ }
79
+
80
+ setLocalHashInfo(hash: string, info: string): boolean {
70
81
  logger.debug(TAG, ',call setLocalHashInfo');
71
82
  return UpdateModuleImpl.setLocalHashInfo(this.context, hash, info);
72
83
  }
@@ -75,9 +86,9 @@ getConstants(): Object {
75
86
  return UpdateModuleImpl.getLocalHashInfo(this.context, hash);
76
87
  }
77
88
 
78
- async setUuid(uuid: string): Promise<boolean> {
89
+ async setUuid(uuid: string): Promise<boolean> {
79
90
  logger.debug(TAG, ',call setUuid');
80
- return UpdateModuleImpl.setUuid(this.context,uuid);
91
+ return UpdateModuleImpl.setUuid(this.context, uuid);
81
92
  }
82
93
 
83
94
  async reloadUpdate(options: { hash: string }): Promise<void> {
@@ -95,31 +106,45 @@ getConstants(): Object {
95
106
  return UpdateModuleImpl.markSuccess(this.context);
96
107
  }
97
108
 
98
- async downloadPatchFromPpk(options: { updateUrl: string; hash: string; originHash: string }): Promise<void> {
109
+ async downloadPatchFromPpk(options: {
110
+ updateUrl: string;
111
+ hash: string;
112
+ originHash: string;
113
+ }): Promise<void> {
99
114
  logger.debug(TAG, ',call downloadPatchFromPpk');
100
115
  return UpdateModuleImpl.downloadPatchFromPpk(this.context, options);
101
116
  }
102
117
 
103
- async downloadPatchFromPackage(options: { updateUrl: string; hash: string }): Promise<void> {
118
+ async downloadPatchFromPackage(options: {
119
+ updateUrl: string;
120
+ hash: string;
121
+ }): Promise<void> {
104
122
  logger.debug(TAG, ',call downloadPatchFromPackage');
105
123
  return UpdateModuleImpl.downloadPatchFromPackage(this.context, options);
106
124
  }
107
125
 
108
- async downloadFullUpdate(options: { updateUrl: string; hash: string }): Promise<void> {
126
+ async downloadFullUpdate(options: {
127
+ updateUrl: string;
128
+ hash: string;
129
+ }): Promise<void> {
109
130
  logger.debug(TAG, ',call downloadFullUpdate');
110
131
  return UpdateModuleImpl.downloadFullUpdate(this.context, options);
111
132
  }
112
133
 
113
- async downloadAndInstallApk(options: { url: string; target: string; hash: string }): Promise<void> {
134
+ async downloadAndInstallApk(options: {
135
+ url: string;
136
+ target: string;
137
+ hash: string;
138
+ }): Promise<void> {
114
139
  logger.debug(TAG, ',call downloadAndInstallApk');
115
140
  return UpdateModuleImpl.downloadAndInstallApk(this.mUiCtx, options);
116
141
  }
117
142
 
118
- addListener(eventName: string): void {
143
+ addListener(_eventName: string): void {
119
144
  logger.debug(TAG, ',call addListener');
120
145
  }
121
146
 
122
- removeListeners(count: number): void {
147
+ removeListeners(_count: number): void {
123
148
  logger.debug(TAG, ',call removeListeners');
124
149
  }
125
150
  }
@@ -101,6 +101,7 @@ export class UpdateContext {
101
101
  params.hash = hash;
102
102
  params.listener = listener;
103
103
  params.targetFile = `${this.rootDir}/${hash}.ppk`;
104
+ params.unzipDirectory = `${this.rootDir}/${hash}`;
104
105
  const downloadTask = new DownloadTask(this.context);
105
106
  await downloadTask.execute(params);
106
107
  } catch (e) {
@@ -162,8 +163,8 @@ export class UpdateContext {
162
163
  const downloadTask = new DownloadTask(this.context);
163
164
  return await downloadTask.execute(params);
164
165
  } catch (e) {
165
- throw e;
166
166
  console.error('Failed to download APK patch:', e);
167
+ throw e;
167
168
  }
168
169
  }
169
170
 
@@ -191,11 +192,11 @@ export class UpdateContext {
191
192
  public static getBundleUrl(
192
193
  context: common.UIAbilityContext,
193
194
  defaultAssetsUrl?: string,
194
- ): string {
195
+ ) {
195
196
  return new UpdateContext(context).getBundleUrl(defaultAssetsUrl);
196
197
  }
197
198
 
198
- public getBundleUrl(defaultAssetsUrl?: string): string {
199
+ public getBundleUrl(defaultAssetsUrl?: string) {
199
200
  UpdateContext.isUsingBundleUrl = true;
200
201
  const currentVersion = this.getCurrentVersion();
201
202
  if (!currentVersion) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-update",
3
- "version": "10.34.8",
3
+ "version": "10.35.0",
4
4
  "description": "react-native hot update",
5
5
  "main": "src/index",
6
6
  "scripts": {
package/src/core.ts CHANGED
@@ -47,7 +47,7 @@ export const currentVersionInfo = _currentVersionInfo;
47
47
 
48
48
  export const isFirstTime: boolean = PushyConstants.isFirstTime;
49
49
  export const rolledBackVersion: string = PushyConstants.rolledBackVersion;
50
- export const isRolledBack: boolean = typeof rolledBackVersion === 'string';
50
+ export const isRolledBack: boolean = !!rolledBackVersion;
51
51
 
52
52
  export const buildTime: string = PushyConstants.buildTime;
53
53
  let uuid = PushyConstants.uuid;
@@ -1,137 +0,0 @@
1
- // hpatch.c
2
- // Copyright 2021 housisong, All rights reserved
3
- #include "hpatch.h"
4
- #include "HDiffPatch/libHDiffPatch/HPatch/patch.h"
5
- #include "HDiffPatch/file_for_patch.h"
6
-
7
- //#define _CompressPlugin_zlib
8
- //#define _CompressPlugin_bz2
9
- #define _CompressPlugin_lzma
10
- #define _CompressPlugin_lzma2
11
- #define _IsNeedIncludeDefaultCompressHead 0
12
- #include "lzma/C/LzmaDec.h"
13
- #include "lzma/C/Lzma2Dec.h"
14
- #include "HDiffPatch/decompress_plugin_demo.h"
15
-
16
- #define kMaxLoadMemOldSize ((1<<20)*8)
17
-
18
- #define _check(v,errorType) do{ \
19
- if (!(v)){ if (result==kHPatch_ok) result=errorType; if (!_isInClear){ goto _clear; }; } }while(0)
20
-
21
- int hpatch_getInfo_by_mem(hpatch_singleCompressedDiffInfo* out_patinfo,
22
- const uint8_t* pat,size_t patsize){
23
- hpatch_TStreamInput patStream;
24
- mem_as_hStreamInput(&patStream,pat,pat+patsize);
25
- if (!getSingleCompressedDiffInfo(out_patinfo,&patStream,0))
26
- return kHPatch_error_info;//data error;
27
- return kHPatch_ok; //ok
28
- }
29
-
30
- static hpatch_TDecompress* getDecompressPlugin(const char* compressType){
31
- #ifdef _CompressPlugin_zlib
32
- if (zlibDecompressPlugin.is_can_open(compressType))
33
- return &zlibDecompressPlugin;
34
- #endif
35
- #ifdef _CompressPlugin_bz2
36
- if (bz2DecompressPlugin.is_can_open(compressType))
37
- return &bz2DecompressPlugin;
38
- #endif
39
- #ifdef _CompressPlugin_lzma
40
- if (lzmaDecompressPlugin.is_can_open(compressType))
41
- return &lzmaDecompressPlugin;
42
- #endif
43
- #ifdef _CompressPlugin_lzma2
44
- if (lzma2DecompressPlugin.is_can_open(compressType))
45
- return &lzma2DecompressPlugin;
46
- #endif
47
- return 0;
48
- }
49
- static int hpatch_by_stream(const hpatch_TStreamInput* old,hpatch_BOOL isLoadOldAllToMem,const hpatch_TStreamInput* pat,
50
- hpatch_TStreamOutput* out_new,const hpatch_singleCompressedDiffInfo* patInfo){
51
- int result=kHPatch_ok;
52
- int _isInClear=hpatch_FALSE;
53
- hpatch_TDecompress* decompressPlugin=0;
54
- uint8_t* temp_cache=0;
55
- size_t temp_cache_size;
56
- hpatch_singleCompressedDiffInfo _patinfo;
57
- hpatch_TStreamInput _old;
58
- {// info
59
- if (!patInfo){
60
- _check(getSingleCompressedDiffInfo(&_patinfo,pat,0),kHPatch_error_info);
61
- patInfo=&_patinfo;
62
- }
63
- _check(old->streamSize==patInfo->oldDataSize,kHPatch_error_old_size);
64
- _check(out_new->streamSize>=patInfo->newDataSize,kHPatch_error_new_size);
65
- out_new->streamSize=patInfo->newDataSize;
66
- if (strlen(patInfo->compressType)>0){
67
- decompressPlugin=getDecompressPlugin(patInfo->compressType);
68
- _check(decompressPlugin,kHPatch_error_compressType);
69
- }
70
- }
71
- {// mem
72
- size_t mem_size;
73
- size_t oldSize=(size_t)old->streamSize;
74
- isLoadOldAllToMem=isLoadOldAllToMem&&(old->streamSize<=kMaxLoadMemOldSize);
75
- temp_cache_size=patInfo->stepMemSize+hpatch_kFileIOBufBetterSize*3;
76
- mem_size=temp_cache_size+(isLoadOldAllToMem?oldSize:0);
77
- temp_cache=malloc(mem_size);
78
- _check(temp_cache,kHPatch_error_malloc);
79
- if (isLoadOldAllToMem){//load old to mem
80
- uint8_t* oldMem=temp_cache+temp_cache_size;
81
- _check(old->read(old,0,oldMem,oldMem+oldSize),kHPatch_error_old_fread);
82
- mem_as_hStreamInput(&_old,oldMem,oldMem+oldSize);
83
- old=&_old;
84
- }
85
- }
86
-
87
- _check(patch_single_compressed_diff(out_new,old,pat,patInfo->diffDataPos,
88
- patInfo->uncompressedSize,decompressPlugin,patInfo->coverCount,
89
- patInfo->stepMemSize,temp_cache,temp_cache+temp_cache_size),kHPatch_error_patch);
90
-
91
- _clear:
92
- _isInClear=hpatch_TRUE;
93
- if (temp_cache){ free(temp_cache); temp_cache=0; }
94
- return result;
95
- }
96
-
97
- int hpatch_by_mem(const uint8_t* old,size_t oldsize,uint8_t* newBuf,size_t newsize,
98
- const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo){
99
- hpatch_TStreamInput oldStream;
100
- hpatch_TStreamInput patStream;
101
- hpatch_TStreamOutput newStream;
102
- mem_as_hStreamInput(&oldStream,old,old+oldsize);
103
- mem_as_hStreamInput(&patStream,pat,pat+patsize);
104
- mem_as_hStreamOutput(&newStream,newBuf,newBuf+newsize);
105
- return hpatch_by_stream(&oldStream,hpatch_FALSE,&patStream,&newStream,patInfo);
106
- }
107
-
108
- int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfile){
109
- int result=kHPatch_ok;
110
- int _isInClear=hpatch_FALSE;
111
- int patch_result;
112
- hpatch_TFileStreamInput oldStream;
113
- hpatch_TFileStreamInput patStream;
114
- hpatch_TFileStreamOutput newStream;
115
- hpatch_TFileStreamInput_init(&oldStream);
116
- hpatch_TFileStreamInput_init(&patStream);
117
- hpatch_TFileStreamOutput_init(&newStream);
118
-
119
- _check(hpatch_TFileStreamInput_open(&oldStream,oldfile),kHPatch_error_old_fopen);
120
- _check(hpatch_TFileStreamInput_open(&patStream,patchfile),kHPatch_error_pat_fopen);
121
- _check(hpatch_TFileStreamOutput_open(&newStream,newfile,~(hpatch_StreamPos_t)0),kHPatch_error_new_fopen);
122
-
123
- patch_result=hpatch_by_stream(&oldStream.base,hpatch_TRUE,&patStream.base,&newStream.base,0);
124
- if (patch_result!=kHPatch_ok){
125
- _check(!oldStream.fileError,kHPatch_error_old_fread);
126
- _check(!patStream.fileError,kHPatch_error_pat_fread);
127
- _check(!newStream.fileError,kHPatch_error_new_fwrite);
128
- _check(hpatch_FALSE,patch_result);
129
- }
130
-
131
- _clear:
132
- _isInClear=hpatch_TRUE;
133
- _check(hpatch_TFileStreamInput_close(&oldStream),kHPatch_error_old_fclose);
134
- _check(hpatch_TFileStreamInput_close(&patStream),kHPatch_error_pat_fclose);
135
- _check(hpatch_TFileStreamOutput_close(&newStream),kHPatch_error_new_fclose);
136
- return result;
137
- }
@@ -1,44 +0,0 @@
1
- // hpatch.h
2
- // import HDiffPatch, support patchData created by "hdiffz -SD -c-lzma2 oldfile newfile patchfile"
3
- // Copyright 2021 housisong, All rights reserved
4
-
5
- #ifndef HDIFFPATCH_PATCH_H
6
- #define HDIFFPATCH_PATCH_H
7
- # include <stdint.h> //for uint8_t
8
- #include "HDiffPatch/libHDiffPatch/HPatch/patch_types.h" //for hpatch_singleCompressedDiffInfo
9
- #ifdef __cplusplus
10
- extern "C" {
11
- #endif
12
-
13
- //result
14
- enum {
15
- kHPatch_ok = 0,
16
- kHPatch_error_malloc =-1,
17
- kHPatch_error_info =-2,
18
- kHPatch_error_compressType =-3,
19
- kHPatch_error_patch =-4,
20
- kHPatch_error_old_fopen =-5,
21
- kHPatch_error_old_fread =-6,
22
- kHPatch_error_old_fclose =-7,
23
- kHPatch_error_pat_fopen =-8,
24
- kHPatch_error_pat_fread =-9,
25
- kHPatch_error_pat_fclose =-10,
26
- kHPatch_error_new_fopen =-11,
27
- kHPatch_error_new_fwrite =-12,
28
- kHPatch_error_new_fclose =-13,
29
- kHPatch_error_old_size =-14,
30
- kHPatch_error_new_size =-15,
31
- };
32
-
33
- int hpatch_getInfo_by_mem(hpatch_singleCompressedDiffInfo* out_patinfo,
34
- const uint8_t* pat,size_t patsize);
35
-
36
- //patInfo can NULL
37
- int hpatch_by_mem(const uint8_t* old,size_t oldsize, uint8_t* newBuf,size_t newsize,
38
- const uint8_t* pat,size_t patsize,const hpatch_singleCompressedDiffInfo* patInfo);
39
- int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfile);
40
-
41
- #ifdef __cplusplus
42
- }
43
- #endif
44
- #endif //HDIFFPATCH_PATCH_H