From 3e4384c2a88a6be8647ce9e65053173bd9989583 Mon Sep 17 00:00:00 2001 From: Eric House Date: Thu, 13 Sep 2012 05:39:44 -0700 Subject: [PATCH] when dict doesn't have built-in md5sum, or when in DEBUG code, call back into java to get a sum. It's very slow for large dicts, but will eventually be in a DB so only done once per dict that doesn't have it. --- xwords4/android/XWords4/jni/anddict.c | 17 +++++++++++ xwords4/android/XWords4/jni/jniutlswrapper.c | 26 +++++++++++----- xwords4/android/XWords4/jni/jniutlswrapper.h | 2 ++ .../org/eehouse/android/xw4/DictUtils.java | 13 +------- .../src/org/eehouse/android/xw4/Utils.java | 17 +++++++++++ .../org/eehouse/android/xw4/jni/JNIUtils.java | 1 + .../eehouse/android/xw4/jni/JNIUtilsImpl.java | 30 +++++++++++++++++-- 7 files changed, 83 insertions(+), 23 deletions(-) diff --git a/xwords4/android/XWords4/jni/anddict.c b/xwords4/android/XWords4/jni/anddict.c index 4bddb2990..1c86f7018 100644 --- a/xwords4/android/XWords4/jni/anddict.c +++ b/xwords4/android/XWords4/jni/anddict.c @@ -340,6 +340,23 @@ parseDict( AndDictionaryCtxt* ctxt, XP_U8 const* ptr, XP_U32 dictLength, goto error; } + if ( NULL == ctxt->super.md5Sum +#ifdef DEBUG + || XP_TRUE +#endif + ) { + JNIEnv* env = ctxt->env; + jstring jsum = and_util_figureMD5Sum( ctxt->jniutil, ptr, end - ptr ); + XP_UCHAR* md5Sum = getStringCopy( MPPARM(ctxt->super.mpool) env, jsum ); + (*env)->DeleteLocalRef( env, jsum ); + if ( NULL == ctxt->super.md5Sum ) { + ctxt->super.md5Sum = md5Sum; + } else { + XP_ASSERT( 0 == XP_STRCMP( ctxt->super.md5Sum, md5Sum ) ); + XP_FREE( ctxt->super.mpool, md5Sum ); + } + } + ctxt->super.nodeSize = nodeSize; if ( !isUTF8 ) { diff --git a/xwords4/android/XWords4/jni/jniutlswrapper.c b/xwords4/android/XWords4/jni/jniutlswrapper.c index 94b52265c..e5d5b5d91 100644 --- a/xwords4/android/XWords4/jni/jniutlswrapper.c +++ b/xwords4/android/XWords4/jni/jniutlswrapper.c @@ -84,14 +84,24 @@ and_util_splitFaces( JNIUtilCtxt* jniutil, const XP_U8* bytes, jsize len, = getMethodID( env, jniutil->jjniutil, "splitFaces", "([BZ)[Ljava/lang/String;" ); - jbyteArray jbytes = (*env)->NewByteArray( env, len ); - - jbyte* jp = (*env)->GetByteArrayElements( env, jbytes, NULL ); - XP_MEMCPY( jp, bytes, len ); - (*env)->ReleaseByteArrayElements( env, jbytes, jp, 0 ); - - strarray = (*env)->CallObjectMethod( env, jniutil->jjniutil, mid, jbytes, - isUTF8 ); + jbyteArray jbytes = makeByteArray( env, len, (jbyte*)bytes ); + strarray = + (*env)->CallObjectMethod( env, jniutil->jjniutil, mid, jbytes, isUTF8 ); (*env)->DeleteLocalRef( env, jbytes ); + return strarray; } + +jstring +and_util_figureMD5Sum( JNIUtilCtxt* jniutil, const XP_U8* bytes, jsize len ) +{ + JNIEnv* env = *jniutil->envp; + jmethodID mid = getMethodID( env, jniutil->jjniutil, "figureMD5Sum", + "([B)Ljava/lang/String;" ); + jbyteArray jbytes = makeByteArray( env, len, (jbyte*)bytes ); + jstring sum = + (*env)->CallObjectMethod( env, jniutil->jjniutil, mid, jbytes ); + (*env)->DeleteLocalRef( env, jbytes ); + + return sum; +} diff --git a/xwords4/android/XWords4/jni/jniutlswrapper.h b/xwords4/android/XWords4/jni/jniutlswrapper.h index 4e0dfea9a..0cc6c53dc 100644 --- a/xwords4/android/XWords4/jni/jniutlswrapper.h +++ b/xwords4/android/XWords4/jni/jniutlswrapper.h @@ -35,5 +35,7 @@ jobject and_util_makeJBitmap( JNIUtilCtxt* jniu, int nCols, int nRows, const jboolean* colors ); jobject and_util_splitFaces( JNIUtilCtxt* jniu, const XP_U8* bytes, int len, XP_Bool isUTF8 ); +jstring and_util_figureMD5Sum( JNIUtilCtxt* jniutil, const XP_U8* bytes, + jsize len ); #endif diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java index 2f19e2ff2..d37f13083 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/DictUtils.java @@ -555,18 +555,7 @@ public class DictUtils { DbgUtils.loge( ioe ); } - if ( null != digest ) { - final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9', - 'a','b','c','d','e','f'}; - char[] chars = new char[digest.length * 2]; - for ( int ii = 0; ii < digest.length; ii++ ) { - int byt = digest[ii] & 0xFF; - chars[ii * 2] = hexArray[byt >> 4]; - chars[ii * 2 + 1] = hexArray[byt & 0x0F]; - } - result = new String(chars); - } - return result; + return Utils.digestToString( digest ); } // figureMD5Sum public static String getMD5SumFor( Context context, DictAndLoc dandl ) diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java index 5c08356ae..8715901de 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/Utils.java @@ -345,6 +345,23 @@ public class Utils { return context.getString( id, args ); } + public static String digestToString( byte[] digest ) + { + String result = null; + if ( null != digest ) { + final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9', + 'a','b','c','d','e','f'}; + char[] chars = new char[digest.length * 2]; + for ( int ii = 0; ii < digest.length; ii++ ) { + int byt = digest[ii] & 0xFF; + chars[ii * 2] = hexArray[byt >> 4]; + chars[ii * 2 + 1] = hexArray[byt & 0x0F]; + } + result = new String(chars); + } + return result; + } + private static void setFirstBootStatics( Context context ) { int thisVersion = 0; diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtils.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtils.java index 03bbe39cb..ce9dff290 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtils.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtils.java @@ -26,4 +26,5 @@ public interface JNIUtils { // Stuff I can't do in C.... String[] splitFaces( byte[] chars, boolean isUTF8 ); + String figureMD5Sum( byte[] bytes ); } \ No newline at end of file diff --git a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtilsImpl.java b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtilsImpl.java index c64c391b1..fc450e1ab 100644 --- a/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtilsImpl.java +++ b/xwords4/android/XWords4/src/org/eehouse/android/xw4/jni/JNIUtilsImpl.java @@ -20,11 +20,12 @@ package org.eehouse.android.xw4.jni; -import android.graphics.drawable.BitmapDrawable; import android.graphics.Bitmap; -import java.util.ArrayList; +import android.graphics.drawable.BitmapDrawable; import java.io.ByteArrayInputStream; import java.io.InputStreamReader; +import java.security.MessageDigest; +import java.util.ArrayList; import org.eehouse.android.xw4.*; @@ -86,4 +87,27 @@ public class JNIUtilsImpl implements JNIUtils { String[] result = al.toArray( new String[al.size()] ); return result; } -} \ No newline at end of file + + public String figureMD5Sum( byte[] bytes ) + { + byte[] digest = null; + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + byte[] buf = new byte[128]; + int nLeft = bytes.length; + int offset = 0; + while ( 0 < nLeft ) { + int len = Math.min( buf.length, nLeft ); + System.arraycopy( bytes, offset, buf, 0, len ); + md.update( buf, 0, len ); + nLeft -= len; + offset += len; + } + digest = md.digest(); + } catch ( java.security.NoSuchAlgorithmException nsae ) { + DbgUtils.loge( nsae ); + } + + return Utils.digestToString( digest ); + } +}