From 7782025e388044bdb31e950b1d9ecc1d8d3040eb Mon Sep 17 00:00:00 2001 From: sisong Date: Sun, 4 Apr 2021 15:50:40 +0800 Subject: [PATCH] jni hdiffPatch() ok --- android/jni/DownloadTask.c | 49 ++++++++++++++++++++++++++++++++++++-- android/jni/hpatch.c | 13 +++++++++- android/jni/hpatch.h | 7 +++++- 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/android/jni/DownloadTask.c b/android/jni/DownloadTask.c index 4644da9..4dfebc2 100644 --- a/android/jni/DownloadTask.c +++ b/android/jni/DownloadTask.c @@ -6,6 +6,7 @@ #include #include "bzlib.h" #include "bspatch.h" +#include "hpatch.h" #include static int64_t offtin(uint8_t *buf) @@ -111,8 +112,52 @@ JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_bsd } +#define _check(v,errInfo) do{ if (!(v)) { _isError=hpatch_TRUE; _errInfo=errInfo; goto _clear; } }while(0) + JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_hdiffPatch (JNIEnv *env, jobject self, jbyteArray origin, jbyteArray patch){ - //todo: - return 0; + 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; + + _check(((originLength==0)||originPtr) && patchPtr && (patchLength>0),"Corrupt patch"); + _check(0!=hpatch_getInfo_by_mem(&patInfo,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"); + } + + _check(0!=hpatch_by_mem(originPtr,originLength,outPtr,newsize, + pat,patsize,&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, _errInfo); + } + return ret; } \ No newline at end of file diff --git a/android/jni/hpatch.c b/android/jni/hpatch.c index 0e34c9c..3d7d646 100644 --- a/android/jni/hpatch.c +++ b/android/jni/hpatch.c @@ -1,8 +1,19 @@ // hpatch.c // Copyright 2021 housisong, All rights reserved +#include "hpatch.h" +#include "HDiffPatch/libHDiffPatch/HPatch/patch.h" + +int hpatch_getInfo_by_mem(struct 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 -1;//data error; + return 0; //ok +} 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 uint8_t* pat,size_t patsize,const struct hpatch_singleCompressedDiffInfo* patInfo){ //todo: return -1; } diff --git a/android/jni/hpatch.h b/android/jni/hpatch.h index 377cb23..e48571e 100644 --- a/android/jni/hpatch.h +++ b/android/jni/hpatch.h @@ -6,8 +6,13 @@ #define HDIFFPATCH_PATCH_H # include //for uint8_t +struct hpatch_singleCompressedDiffInfo; +int hpatch_getInfo_by_mem(struct 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 uint8_t* pat,size_t patsize,const struct hpatch_singleCompressedDiffInfo* patInfo); int hpatch_by_file(const char* oldfile, const char* newfile, const char* patchfile); #endif //HDIFFPATCH_PATCH_H \ No newline at end of file