mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-29 08:34:37 +01:00
handle synonyms in non-special tiles for Android: wordlists load and
display, and searching using lower case works. Specials (e.g. Catalan changes) not yet supported.
This commit is contained in:
parent
2873d08974
commit
cae631eeb0
4 changed files with 84 additions and 25 deletions
|
@ -216,36 +216,42 @@ static void
|
|||
splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt, const XP_U8* ptr,
|
||||
int nFaceBytes, int nFaces, XP_Bool isUTF8 )
|
||||
{
|
||||
XP_UCHAR facesBuf[nFaces*4]; /* seems a reasonable upper bound... */
|
||||
XP_UCHAR facesBuf[nFaces*16]; /* seems a reasonable upper bound... */
|
||||
int indx = 0;
|
||||
int offsets[nFaces];
|
||||
int nBytes;
|
||||
int ii;
|
||||
int ii, jj;
|
||||
|
||||
jobject jstrarr = and_util_splitFaces( ctxt->jniutil, ptr, nFaceBytes,
|
||||
isUTF8 );
|
||||
XP_ASSERT( (*env)->GetArrayLength( env, jstrarr ) == nFaces );
|
||||
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
jobject jstr = (*env)->GetObjectArrayElement( env, jstrarr, ii );
|
||||
jobject jstrs = (*env)->GetObjectArrayElement( env, jstrarr, ii );
|
||||
offsets[ii] = indx;
|
||||
nBytes = (*env)->GetStringUTFLength( env, jstr );
|
||||
int nAlternates = (*env)->GetArrayLength( env, jstrs );
|
||||
for ( jj = 0; jj < nAlternates; ++jj ) {
|
||||
jobject jstr = (*env)->GetObjectArrayElement( env, jstrs, jj );
|
||||
nBytes = (*env)->GetStringUTFLength( env, jstr );
|
||||
|
||||
const char* bytes = (*env)->GetStringUTFChars( env, jstr, NULL );
|
||||
char* end;
|
||||
long numval = strtol( bytes, &end, 10 );
|
||||
if ( end > bytes ) {
|
||||
XP_ASSERT( numval < 32 );
|
||||
nBytes = 1;
|
||||
facesBuf[indx] = (XP_UCHAR)numval;
|
||||
} else {
|
||||
XP_MEMCPY( &facesBuf[indx], bytes, nBytes );
|
||||
const char* bytes = (*env)->GetStringUTFChars( env, jstr, NULL );
|
||||
char* end;
|
||||
long numval = strtol( bytes, &end, 10 );
|
||||
if ( end > bytes ) {
|
||||
XP_ASSERT( numval < 32 );
|
||||
XP_ASSERT( jj == 0 );
|
||||
nBytes = 1;
|
||||
facesBuf[indx] = (XP_UCHAR)numval;
|
||||
} else {
|
||||
XP_MEMCPY( &facesBuf[indx], bytes, nBytes );
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars( env, jstr, bytes );
|
||||
deleteLocalRef( env, jstr );
|
||||
indx += nBytes;
|
||||
facesBuf[indx++] = '\0';
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars( env, jstr, bytes );
|
||||
deleteLocalRef( env, jstr );
|
||||
|
||||
indx += nBytes;
|
||||
facesBuf[indx++] = '\0';
|
||||
deleteLocalRef( env, jstrs );
|
||||
XP_ASSERT( indx < VSIZE(facesBuf) );
|
||||
}
|
||||
deleteLocalRef( env, jstrarr );
|
||||
|
@ -261,6 +267,7 @@ splitFaces_via_java( JNIEnv* env, AndDictionaryCtxt* ctxt, const XP_U8* ptr,
|
|||
|
||||
XP_ASSERT( !ctxt->super.faces );
|
||||
ctxt->super.faces = faces;
|
||||
ctxt->super.facesEnd = faces + indx;
|
||||
XP_ASSERT( !ctxt->super.facePtrs );
|
||||
ctxt->super.facePtrs = ptrs;
|
||||
} /* splitFaces_via_java */
|
||||
|
@ -348,16 +355,30 @@ parseDict( AndDictionaryCtxt* ctxt, XP_U8 const* ptr, XP_U32 dictLength,
|
|||
JNIEnv* env = ctxt->env;
|
||||
jstring jsum = and_util_getMD5SumFor( ctxt->jniutil, ctxt->super.name,
|
||||
NULL, 0 );
|
||||
XP_UCHAR* md5Sum = NULL;
|
||||
/* If we have a cached sum, check that it's correct. */
|
||||
if ( NULL != jsum && NULL != ctxt->super.md5Sum ) {
|
||||
md5Sum = getStringCopy( MPPARM(ctxt->super.mpool) env, jsum );
|
||||
if ( 0 != XP_STRCMP( ctxt->super.md5Sum, md5Sum ) ) {
|
||||
deleteLocalRef( env, jsum );
|
||||
jsum = NULL;
|
||||
XP_FREE( ctxt->super.mpool, md5Sum );
|
||||
md5Sum = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( NULL == jsum ) {
|
||||
jsum = and_util_getMD5SumFor( ctxt->jniutil, ctxt->super.name,
|
||||
ptr, end - ptr );
|
||||
}
|
||||
XP_UCHAR* md5Sum = getStringCopy( MPPARM(ctxt->super.mpool) env, jsum );
|
||||
if ( NULL == md5Sum ) {
|
||||
md5Sum = getStringCopy( MPPARM(ctxt->super.mpool) env, jsum );
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ and_util_splitFaces( JNIUtilCtxt* jniutil, const XP_U8* bytes, jsize len,
|
|||
JNIEnv* env = *jniutil->envp;
|
||||
jmethodID mid
|
||||
= getMethodID( env, jniutil->jjniutil, "splitFaces",
|
||||
"([BZ)[Ljava/lang/String;" );
|
||||
"([BZ)[[Ljava/lang/String;" );
|
||||
|
||||
jbyteArray jbytes = makeByteArray( env, len, (jbyte*)bytes );
|
||||
strarray =
|
||||
|
|
|
@ -25,6 +25,6 @@ import android.graphics.drawable.BitmapDrawable;
|
|||
public interface JNIUtils {
|
||||
|
||||
// Stuff I can't do in C....
|
||||
String[] splitFaces( byte[] chars, boolean isUTF8 );
|
||||
String[][] splitFaces( byte[] chars, boolean isUTF8 );
|
||||
String getMD5SumFor( String dictName, byte[] bytes );
|
||||
}
|
|
@ -28,10 +28,14 @@ import java.io.InputStreamReader;
|
|||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.eehouse.android.xw4.*;
|
||||
|
||||
public class JNIUtilsImpl implements JNIUtils {
|
||||
|
||||
private static final char SYNONYM_DELIM = ' ';
|
||||
|
||||
private static JNIUtilsImpl s_impl = null;
|
||||
private Context m_context;
|
||||
|
||||
|
@ -51,10 +55,15 @@ public class JNIUtilsImpl implements JNIUtils {
|
|||
* convert into individual strings. The 0 is the problem: it's
|
||||
* not valid utf8. So turn it and the other nums into strings and
|
||||
* catch them on the other side.
|
||||
*
|
||||
* Changes for "synonyms" (A and a being the same tile): return an
|
||||
* array of Strings for each face. Each face is
|
||||
* <letter>[<delim><letter]*, so for each loop until the delim
|
||||
* isn't found.
|
||||
*/
|
||||
public String[] splitFaces( byte[] chars, boolean isUTF8 )
|
||||
public String[][] splitFaces( byte[] chars, boolean isUTF8 )
|
||||
{
|
||||
ArrayList<String> al = new ArrayList<String>();
|
||||
ArrayList<String[]> faces = new ArrayList<String[]>();
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream( chars );
|
||||
InputStreamReader isr;
|
||||
try {
|
||||
|
@ -66,6 +75,9 @@ public class JNIUtilsImpl implements JNIUtils {
|
|||
|
||||
int[] codePoints = new int[1];
|
||||
|
||||
// "A aB bC c"
|
||||
boolean lastWasDelim = false;
|
||||
ArrayList<String> face = null;
|
||||
for ( ; ; ) {
|
||||
int chr = -1;
|
||||
try {
|
||||
|
@ -74,7 +86,12 @@ public class JNIUtilsImpl implements JNIUtils {
|
|||
DbgUtils.logf( ioe.toString() );
|
||||
}
|
||||
if ( -1 == chr ) {
|
||||
addFace( faces, face );
|
||||
break;
|
||||
} else if ( SYNONYM_DELIM == chr ) {
|
||||
Assert.assertNotNull( face );
|
||||
lastWasDelim = true;
|
||||
continue;
|
||||
} else {
|
||||
String letter;
|
||||
if ( chr < 32 ) {
|
||||
|
@ -83,14 +100,35 @@ public class JNIUtilsImpl implements JNIUtils {
|
|||
codePoints[0] = chr;
|
||||
letter = new String( codePoints, 0, 1 );
|
||||
}
|
||||
al.add( letter );
|
||||
// Ok, we have a letter. Is it part of an existing
|
||||
// one or the start of a new? If the latter, insert
|
||||
// what we have before starting over.
|
||||
if ( null == face ) { // start of a new, clearly
|
||||
// do nothing
|
||||
} else {
|
||||
Assert.assertTrue( 0 < face.size() );
|
||||
if ( !lastWasDelim ) {
|
||||
addFace( faces, face );
|
||||
face = null;
|
||||
}
|
||||
}
|
||||
lastWasDelim = false;
|
||||
if ( null == face ) {
|
||||
face = new ArrayList<String>();
|
||||
}
|
||||
face.add( letter );
|
||||
}
|
||||
}
|
||||
|
||||
String[] result = al.toArray( new String[al.size()] );
|
||||
String[][] result = faces.toArray( new String[faces.size()][] );
|
||||
return result;
|
||||
}
|
||||
|
||||
private void addFace( ArrayList<String[]> faces, ArrayList<String> face )
|
||||
{
|
||||
faces.add( face.toArray( new String[face.size()] ) );
|
||||
}
|
||||
|
||||
public String getMD5SumFor( String dictName, byte[] bytes )
|
||||
{
|
||||
String result = null;
|
||||
|
|
Loading…
Add table
Reference in a new issue