cleanup around jni wrapping and checking

Separated the refcounting and ptr-as-long wrapping aspects of GamePtr
into a superclass that others might later inherit from. Cleaned up
dict_iter entrypoints, and added sanity checks to both structs so I'll
quickly notice if I get the ptr management wrong.
This commit is contained in:
Eric House 2020-04-28 20:13:59 -07:00
parent 9aaeee19b1
commit 0078e58535
2 changed files with 214 additions and 154 deletions

View file

@ -36,76 +36,107 @@ import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType;
public class XwJNI {
private static final String TAG = XwJNI.class.getSimpleName();
public static class GamePtr implements AutoCloseable {
private long m_ptrGame = 0;
abstract static class PtrWrapper {
// This class provides ref counting and wrapping of a long that's
// really a pointer returned by jni code. In addition to the
// refcounting, which doesn't have to be used in a meaningful way, it
// provides type safety (avoids a long representing every jni
// datatype. BUT there's cost to the jni code calling back into java
// (the ptr() method) to get the long. I originally did this to wrap
// the long that represents DictIter state, then pulled that on
// noticing a slowdown in wordlist browsing. Still, I like having two
// classes here so I'm keeping that.
private long m_ptr;
private int m_refCount = 0;
private long m_rowid;
private String mStack;
private GamePtr( long ptr, long rowid )
PtrWrapper( long ptr )
{
m_ptrGame = ptr;
m_rowid = rowid;
mStack = android.util.Log.getStackTraceString(new Exception());
Quarantine.recordOpened( rowid );
m_ptr = ptr;
if ( BuildConfig.DEBUG ) {
mStack = android.util.Log.getStackTraceString(new Exception());
}
}
public synchronized long ptr()
public long ptr()
{
Assert.assertTrue( 0 != m_ptrGame );
return m_ptrGame;
Assert.assertTrueNR( 0 != m_ptr );
return m_ptr;
}
public synchronized GamePtr retain()
public synchronized PtrWrapper retain()
{
++m_refCount;
Log.d( TAG, "retain(this=%H, rowid=%d): refCount now %d",
this, m_rowid, m_refCount );
return this;
}
public long getRowid() { return m_rowid; }
abstract void onFinalRelease( long ptr );
// Force (via an assert in finalize() below) that this is called. It's
// Force (via an assert in finalize() below) that this is called. It's
// better if jni stuff isn't being done on the finalizer thread
public synchronized void release()
{
--m_refCount;
// Log.d( TAG, "%s.release(this=%H, rowid=%d): refCount now %d",
// getClass().getName(), this, m_rowid, m_refCount );
if ( 0 == m_refCount ) {
if ( 0 != m_ptrGame ) {
Quarantine.recordClosed( m_rowid );
if ( haveEnv( getJNI().m_ptrGlobals ) ) {
game_dispose( this ); // will crash if haveEnv fails
} else {
Log.d( TAG, "release(): no ENV!!! (this=%H, rowid=%d)",
this, m_rowid );
Assert.failDbg(); // seen on Play Store console
}
m_ptrGame = 0;
}
onFinalRelease( m_ptr );
m_ptr = 0;
} else {
Assert.assertTrue( m_refCount > 0 || !BuildConfig.DEBUG );
}
}
// @Override
public void finalize() throws java.lang.Throwable
{
if ( BuildConfig.DEBUG && (0 != m_refCount || 0 != m_ptr) ) {
Log.e( TAG, "finalize(): called prematurely: refCount: %d"
+ "; ptr: %d; creator: %s", m_refCount, m_ptr, mStack );
}
super.finalize();
}
}
public static class GamePtr extends PtrWrapper implements AutoCloseable {
private long m_rowid;
private GamePtr( long ptr, long rowid )
{
super( ptr );
m_rowid = rowid;
Quarantine.recordOpened( rowid );
}
public long getRowid() { return m_rowid; }
@Override
void onFinalRelease( long ptr )
{
if ( 0 != ptr ) {
Quarantine.recordClosed( m_rowid );
if ( haveEnv( getJNI().m_ptrGlobals ) ) {
game_dispose( this ); // will crash if haveEnv fails
} else {
Log.d( TAG, "release(): no ENV!!! (this=%H, rowid=%d)",
this, m_rowid );
Assert.failDbg(); // seen on Play Store console
}
}
}
public GamePtr retain()
{
super.retain();
// Log.d( TAG, "retain(this=%H, rowid=%d): refCount now %d",
// this, m_rowid, m_refCount );
return this;
}
@Override
public void close()
{
release();
}
// @Override
public void finalize() throws java.lang.Throwable
{
if ( BuildConfig.DEBUG && (0 != m_refCount || 0 != m_ptrGame) ) {
Log.e( TAG, "finalize(): called prematurely: refCount: %d"
+ "; ptr: %d; creator: %s", m_refCount, m_ptrGame, mStack );
}
super.finalize();
}
}
} // GamePtr
private static XwJNI s_JNI = null;
private static synchronized XwJNI getJNI()
@ -559,5 +590,6 @@ public class XwJNI {
String fromPhone,
int wantPort);
// This always returns true on release builds now.
private static native boolean haveEnv( long jniState );
}

View file

@ -116,9 +116,9 @@ releaseMPool( JNIGlobalState* globalState )
#define GAMEPTR_IS_OBJECT
#ifdef GAMEPTR_IS_OBJECT
typedef jobject GamePtrType;
typedef jobject PtrType;
#else
typedef long GamePtrType;
typedef long PtrType;
#endif
#ifdef LOG_MAPPING
@ -347,8 +347,8 @@ tilesArrayToTileSet( JNIEnv* env, jintArray jtiles, TrayTileSet* tset )
}
#ifdef GAMEPTR_IS_OBJECT
static JNIState*
getState( JNIEnv* env, GamePtrType gamePtr, const char* func )
static void*
getState( JNIEnv* env, PtrType gamePtr, const char* func )
{
#ifdef DEBUG
if ( NULL == gamePtr ) {
@ -359,7 +359,7 @@ getState( JNIEnv* env, GamePtrType gamePtr, const char* func )
XP_ASSERT( NULL != gamePtr ); /* fired */
jmethodID mid = getMethodID( env, gamePtr, "ptr", "()J" );
XP_ASSERT( !!mid );
return (JNIState*)(*env)->CallLongMethod( env, gamePtr, mid );
return (void*)(*env)->CallLongMethod( env, gamePtr, mid );
}
#else
# define getState( env, gamePtr, func ) ((JNIState*)(gamePtr))
@ -977,14 +977,17 @@ struct _JNIState {
XP_U16 lastSavedSize;
#ifdef DEBUG
const char* envSetterFunc;
XP_U32 guard;
#endif
MPSLOT
};
#define GAME_GUARD 0x453627
#define XWJNI_START() { \
JNIState* state = getState( env, gamePtr, __func__ ); \
XP_ASSERT( state->guard == GAME_GUARD ); \
MPSLOT; \
MPASSIGN( mpool, state->mpool); \
MPASSIGN( mpool, state->mpool ); \
XP_ASSERT( !!state->globalJNI ); \
MAP_THREAD( &state->globalJNI->ti, env ); \
@ -1003,6 +1006,9 @@ Java_org_eehouse_android_xw4_jni_XwJNI_initGameJNI
MemPoolCtx* mpool = ((JNIGlobalState*)jniGlobalPtr)->mpool;
#endif
JNIState* state = (JNIState*)XP_CALLOC( mpool, sizeof(*state) );
#ifdef DEBUG
state->guard = GAME_GUARD;
#endif
state->globalJNI = (JNIGlobalState*)jniGlobalPtr;
MAP_THREAD( &state->globalJNI->ti, env );
AndGameGlobals* globals = &state->globals;
@ -1030,7 +1036,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_envDone
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject j_gi,
( JNIEnv* env, jclass C, PtrType gamePtr, jobject j_gi,
jobjectArray j_names, jobjectArray j_dicts, jobjectArray j_paths,
jstring j_lang, jobject j_util, jobject j_draw, jobject j_cp,
jobject j_procs )
@ -1079,9 +1085,10 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeNewGame
} /* makeNewGame */
JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
( JNIEnv* env, jclass claz, GamePtrType gamePtr )
( JNIEnv* env, jclass claz, PtrType gamePtr )
{
JNIState* state = getState( env, gamePtr, __func__ );
XP_ASSERT( state->guard == GAME_GUARD );
#ifdef MEM_DEBUG
MemPoolCtx* mpool = state->mpool;
@ -1099,12 +1106,15 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_game_1dispose
MAP_REMOVE( &state->globalJNI->ti, env );
#ifdef DEBUG
XP_MEMSET( state, -1, sizeof(*state) );
#endif
XP_FREE( mpool, state );
} /* game_dispose */
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi,
( JNIEnv* env, jclass C, PtrType gamePtr, jbyteArray jstream, jobject /*out*/jgi,
jobjectArray jdictNames, jobjectArray jdicts, jobjectArray jpaths,
jstring jlang, jobject jutil, jobject jdraw, jobject jcp, jobject jprocs )
{
@ -1161,7 +1171,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1makeFromStream
JNIEXPORT jbyteArray JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveToStream
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi )
{
jbyteArray result;
XWJNI_START_GLOBALS();
@ -1191,7 +1201,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveToStream
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveSucceeded
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
game_saveSucceeded( &state->game, env, state->curSaveCount );
@ -1200,7 +1210,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1saveSucceeded
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jdraw )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jdraw )
{
XWJNI_START_GLOBALS();
@ -1215,7 +1225,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setDraw
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1invalAll
( JNIEnv *env, jclass C, GamePtrType gamePtr )
( JNIEnv *env, jclass C, PtrType gamePtr )
{
XWJNI_START();
board_invalAll( state->game.board );
@ -1224,7 +1234,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1invalAll
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw
( JNIEnv *env, jclass C, GamePtrType gamePtr )
( JNIEnv *env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1235,7 +1245,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1draw
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1drawSnapshot
( JNIEnv *env, jclass C, GamePtrType gamePtr, jobject jdraw, jint width,
( JNIEnv *env, jclass C, PtrType gamePtr, jobject jdraw, jint width,
jint height )
{
XWJNI_START();
@ -1248,7 +1258,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1drawSnapshot
#ifdef COMMON_LAYOUT
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi, jint left, jint top,
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi, jint left, jint top,
jint width, jint height, jint scorePct, jint trayPct, jint scoreWidth,
jint fontWidth, jint fontHt, jboolean squareTiles, jobject jdims )
{
@ -1271,7 +1281,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1figureLayout
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jdims )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jdims )
{
XWJNI_START();
BoardDims dims;
@ -1284,7 +1294,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1applyLayout
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
(JNIEnv *env, jclass C, GamePtrType gamePtr, jint left, jint top, jint width,
(JNIEnv *env, jclass C, PtrType gamePtr, jint left, jint top, jint width,
jint height, jint maxCellSize, jboolean lefty )
{
XWJNI_START();
@ -1295,7 +1305,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setPos
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setScoreboardLoc
( JNIEnv *env, jclass C, GamePtrType gamePtr, jint left, jint top,
( JNIEnv *env, jclass C, PtrType gamePtr, jint left, jint top,
jint width, jint height, jboolean divideHorizontally )
{
XWJNI_START();
@ -1306,7 +1316,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setScoreboardLoc
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setTrayLoc
( JNIEnv *env, jclass C, GamePtrType gamePtr, jint left, jint top,
( JNIEnv *env, jclass C, PtrType gamePtr, jint left, jint top,
jint width, jint height, jint minDividerWidth )
{
XWJNI_START();
@ -1318,7 +1328,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setTrayLoc
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint zoomBy, jbooleanArray jCanZoom )
( JNIEnv* env, jclass C, PtrType gamePtr, jint zoomBy, jbooleanArray jCanZoom )
{
jboolean result;
XWJNI_START();
@ -1333,7 +1343,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1zoom
#ifdef XWFEATURE_ACTIVERECT
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1getActiveRect
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jrect, jintArray dims )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jrect, jintArray dims )
{
jboolean result;
XWJNI_START();
@ -1358,7 +1368,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getActiveRect
#ifdef POINTER_SUPPORT
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenDown
(JNIEnv *env, jclass C, GamePtrType gamePtr, jint xx, jint yy, jbooleanArray barray )
(JNIEnv *env, jclass C, PtrType gamePtr, jint xx, jint yy, jbooleanArray barray )
{
jboolean result;
XWJNI_START();
@ -1370,7 +1380,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenDown
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenMove
( JNIEnv *env, jclass C, GamePtrType gamePtr, jint xx, jint yy )
( JNIEnv *env, jclass C, PtrType gamePtr, jint xx, jint yy )
{
jboolean result;
XWJNI_START();
@ -1381,7 +1391,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenMove
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenUp
( JNIEnv *env, jclass C, GamePtrType gamePtr, jint xx, jint yy )
( JNIEnv *env, jclass C, PtrType gamePtr, jint xx, jint yy )
{
jboolean result;
XWJNI_START();
@ -1392,7 +1402,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handlePenUp
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1containsPt
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint xx, jint yy )
( JNIEnv* env, jclass C, PtrType gamePtr, jint xx, jint yy )
{
jboolean result;
XWJNI_START();
@ -1404,7 +1414,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1containsPt
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1juggleTray
(JNIEnv* env, jclass C, GamePtrType gamePtr )
(JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1415,7 +1425,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1juggleTray
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1getTrayVisState
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
jboolean result;
XWJNI_START();
@ -1426,7 +1436,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getTrayVisState
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1getSelPlayer
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
jint result;
XWJNI_START();
@ -1437,7 +1447,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getSelPlayer
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1passwordProvided
(JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jstring jpasswd )
(JNIEnv* env, jclass C, PtrType gamePtr, jint player, jstring jpasswd )
{
jboolean result;
XWJNI_START();
@ -1450,7 +1460,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1passwordProvided
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1hideTray
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
jboolean result;
XWJNI_START();
@ -1461,7 +1471,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1hideTray
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1showTray
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
jboolean result;
XWJNI_START();
@ -1472,7 +1482,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1showTray
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1beginTrade
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1483,7 +1493,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1beginTrade
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1endTrade
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1494,7 +1504,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1endTrade
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1setBlankValue
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player,
( JNIEnv* env, jclass C, PtrType gamePtr, jint player,
jint col, jint row, jint tile )
{
jboolean result;
@ -1506,7 +1516,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1setBlankValue
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1toggle_1showValues
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1517,7 +1527,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1toggle_1showValues
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn
( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean phoniesConfirmed,
( JNIEnv* env, jclass C, PtrType gamePtr, jboolean phoniesConfirmed,
jboolean turnConfirmed, jintArray jNewTiles )
{
jboolean result;
@ -1538,7 +1548,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1commitTurn
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1flip
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
jboolean result;
XWJNI_START();
@ -1549,7 +1559,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1flip
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1replaceTiles
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
jboolean result;
XWJNI_START();
@ -1560,7 +1570,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1replaceTiles
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1redoReplacedTiles
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1571,7 +1581,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1redoReplacedTiles
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1reset
(JNIEnv* env, jclass C, GamePtrType gamePtr )
(JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
server_reset( state->game.server, env, state->game.comms );
@ -1580,7 +1590,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1reset
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1handleUndo
(JNIEnv* env, jclass C, GamePtrType gamePtr)
(JNIEnv* env, jclass C, PtrType gamePtr)
{
XWJNI_START();
server_handleUndo( state->game.server, env, 0 );
@ -1589,7 +1599,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1handleUndo
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1do
(JNIEnv* env, jclass C, GamePtrType gamePtr )
(JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1601,7 +1611,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1do
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1tilesPicked
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jintArray jNewTiles )
( JNIEnv* env, jclass C, PtrType gamePtr, jint player, jintArray jNewTiles )
{
XWJNI_START();
TrayTileSet newTiles;
@ -1612,7 +1622,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1tilesPicked
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1countTilesInPool
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jint result;
XWJNI_START();
@ -1623,7 +1633,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1countTilesInPool
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1resetEngine
(JNIEnv* env, jclass C, GamePtrType gamePtr )
(JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
board_resetEngine( state->game.board );
@ -1632,7 +1642,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1resetEngine
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1requestHint
( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean useLimits,
( JNIEnv* env, jclass C, PtrType gamePtr, jboolean useLimits,
jboolean goBack, jbooleanArray workRemains )
{
jboolean result;
@ -1654,7 +1664,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1requestHint
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_timerFired
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint why, jint when, jint handle )
( JNIEnv* env, jclass C, PtrType gamePtr, jint why, jint when, jint handle )
{
jboolean result;
XWJNI_START_GLOBALS();
@ -1666,7 +1676,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_timerFired
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1formatRemainingTiles
(JNIEnv* env, jclass C, GamePtrType gamePtr )
(JNIEnv* env, jclass C, PtrType gamePtr )
{
jstring result;
XWJNI_START_GLOBALS();
@ -1682,7 +1692,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1formatRemainingTiles
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1formatDictCounts
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint nCols )
( JNIEnv* env, jclass C, PtrType gamePtr, jint nCols )
{
jstring result;
XWJNI_START_GLOBALS();
@ -1696,7 +1706,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1formatDictCounts
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1getGameIsOver
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -1707,7 +1717,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1getGameIsOver
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_model_1writeGameHistory
( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean gameOver )
( JNIEnv* env, jclass C, PtrType gamePtr, jboolean gameOver )
{
jstring result;
XWJNI_START_GLOBALS();
@ -1722,7 +1732,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1writeGameHistory
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNMoves
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jint result;
XWJNI_START();
@ -1735,7 +1745,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNMoves
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNumTilesInTray
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player )
( JNIEnv* env, jclass C, PtrType gamePtr, jint player )
{
jint result;
XWJNI_START();
@ -1747,7 +1757,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getNumTilesInTray
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint player, jobject jlmi )
( JNIEnv* env, jclass C, PtrType gamePtr, jint player, jobject jlmi )
{
XWJNI_START();
XP_ASSERT( !!state->game.model );
@ -1768,7 +1778,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_model_1getPlayersLastScore
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1writeFinalScores
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jstring result;
XWJNI_START_GLOBALS();
@ -1792,7 +1802,7 @@ and_send_on_close( XWStreamCtxt* stream, XWEnv xwe, void* closure )
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1initClientConnection
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
LOG_FUNC();
@ -1807,7 +1817,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1initClientConnection
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1start
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
CommsCtxt* comms = state->game.comms;
@ -1819,7 +1829,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1start
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1stop
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
CommsCtxt* comms = state->game.comms;
@ -1831,7 +1841,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1stop
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resetSame
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
if ( !!state->game.comms ) {
@ -1842,7 +1852,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resetSame
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddr
(JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jaddr )
(JNIEnv* env, jclass C, PtrType gamePtr, jobject jaddr )
{
XWJNI_START();
XP_ASSERT( state->game.comms );
@ -1854,7 +1864,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddr
JNIEXPORT jobjectArray JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrs
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jobjectArray result = NULL;
XWJNI_START();
@ -1882,7 +1892,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrs
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1augmentHostAddr
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jaddr )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jaddr )
{
XWJNI_START();
if ( state->game.comms ) {
@ -1897,7 +1907,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1augmentHostAddr
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1receiveMessage
( JNIEnv* env, jclass C, GamePtrType gamePtr, jbyteArray jstream, jobject jaddr )
( JNIEnv* env, jclass C, PtrType gamePtr, jbyteArray jstream, jobject jaddr )
{
jboolean result;
XWJNI_START_GLOBALS();
@ -1922,7 +1932,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1receiveMessage
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1summarize
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jsummary )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jsummary )
{
XWJNI_START();
ModelCtxt* model = state->game.model;
@ -2016,7 +2026,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1summarize
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1server_1prefsChanged
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jcp )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jcp )
{
jboolean result;
XWJNI_START();
@ -2034,7 +2044,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1server_1prefsChanged
#ifdef KEYBOARD_NAV
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1getFocusOwner
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jint result;
XWJNI_START();
@ -2045,7 +2055,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1getFocusOwner
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1focusChanged
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint typ )
( JNIEnv* env, jclass C, PtrType gamePtr, jint typ )
{
jboolean result;
XWJNI_START();
@ -2058,7 +2068,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1focusChanged
#ifdef KEYBOARD_NAV
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1handleKey
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jkey, jboolean jup,
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jkey, jboolean jup,
jbooleanArray jhandled )
{
jboolean result;
@ -2080,7 +2090,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_board_1handleKey
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1getGi
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi )
{
XWJNI_START_GLOBALS();
setJGI( env, jgi, globals->gi );
@ -2109,7 +2119,7 @@ static const SetInfo gsi_bools[] = {
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgsi )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgsi )
{
XWJNI_START();
GameStateInfo info;
@ -2123,7 +2133,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1getState
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1hasComms
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -2135,7 +2145,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1hasComms
#ifdef XWFEATURE_CHANGEDICT
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_game_1changeDict
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jgi, jstring jname,
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jgi, jstring jname,
jbyteArray jDictBytes, jstring jpath )
{
XWJNI_START_GLOBALS();
@ -2154,7 +2164,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_game_1changeDict
JNIEXPORT jint JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1resendAll
( JNIEnv* env, jclass C, GamePtrType gamePtr, jboolean force, jobject jFilter,
( JNIEnv* env, jclass C, PtrType gamePtr, jboolean force, jobject jFilter,
jboolean thenAck )
{
jint result;
@ -2194,7 +2204,7 @@ onGotOne( void* closure, XWEnv xwe, XP_U8* msg, XP_U16 len, MsgID XP_UNUSED(msgI
JNIEXPORT jobjectArray JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getPending
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jobjectArray result = NULL;
XWJNI_START();
@ -2215,7 +2225,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getPending
#ifdef XWFEATURE_COMMSACK
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1ackAny
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
XP_ASSERT( !!state->game.comms );
@ -2226,7 +2236,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1ackAny
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1transportFailed
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject failedTyp )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject failedTyp )
{
XWJNI_START();
XP_ASSERT( !!state->game.comms );
@ -2238,7 +2248,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1transportFailed
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1isConnected
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jboolean result;
XWJNI_START();
@ -2249,7 +2259,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1isConnected
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1formatRelayID
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint indx )
( JNIEnv* env, jclass C, PtrType gamePtr, jint indx )
{
jstring result = NULL;
XWJNI_START();
@ -2268,7 +2278,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1formatRelayID
JNIEXPORT jstring JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
jstring result = NULL;
#ifdef DEBUG
@ -2287,7 +2297,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1dropHostAddr
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp )
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jConnTyp )
{
LOG_FUNC();
XWJNI_START();
@ -2302,7 +2312,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1dropHostAddr
#ifdef DEBUG
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1setAddrDisabled
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp,
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jConnTyp,
jboolean forSend, jboolean val )
{
XWJNI_START();
@ -2316,7 +2326,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1setAddrDisabled
JNIEXPORT jboolean JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getAddrDisabled
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp,
( JNIEnv* env, jclass C, PtrType gamePtr, jobject jConnTyp,
jboolean forSend )
{
jboolean result = XP_FALSE;
@ -2345,7 +2355,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_haveEnv
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_server_1endGame
( JNIEnv* env, jclass C, GamePtrType gamePtr )
( JNIEnv* env, jclass C, PtrType gamePtr )
{
XWJNI_START();
XP_ASSERT( !!state->game.server );
@ -2354,7 +2364,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_server_1endGame
}
JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1pause
( JNIEnv* env, jclass C, GamePtrType gamePtr, jstring jmsg )
( JNIEnv* env, jclass C, PtrType gamePtr, jstring jmsg )
{
XWJNI_START();
XP_ASSERT( !!state->game.board );
@ -2367,7 +2377,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1pause
}
JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1unpause
( JNIEnv* env, jclass C, GamePtrType gamePtr, jstring jmsg )
( JNIEnv* env, jclass C, PtrType gamePtr, jstring jmsg )
{
XWJNI_START();
XP_ASSERT( !!state->game.board );
@ -2380,7 +2390,7 @@ JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_board_1unpause
#ifdef XWFEATURE_CHAT
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_board_1sendChat
( JNIEnv* env, jclass C, GamePtrType gamePtr, jstring jmsg )
( JNIEnv* env, jclass C, PtrType gamePtr, jstring jmsg )
{
XWJNI_START();
XP_ASSERT( !!state->game.server );
@ -2402,13 +2412,14 @@ typedef struct _DictIterData {
DictIter iter;
IndexData idata;
XP_U16 depth;
#ifdef MEM_DEBUG
MemPoolCtx* mpool;
#ifdef DEBUG
XP_U32 guard;
#endif
} DictIterData;
static void makeIndex( DictIterData* data );
static void freeIndices( DictIterData* data );
#define GI_GUARD 0x89ab72
JNIEXPORT jlong JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_di_1init
@ -2428,34 +2439,43 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1init
data->globalState = globalState;
data->dict = dict;
data->depth = 2;
#ifdef MEM_DEBUG
data->mpool = globalState->mpool;
#ifdef DEBUG
data->guard = GI_GUARD;
#endif
closure = (jlong)data;
}
return closure;
}
#define DI_HEADER() { \
DictIterData* data = (DictIterData*)closure; \
XP_ASSERT( NULL == data || data->guard == GI_GUARD ); \
#define DI_HEADER_END() \
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_di_1setMinMax
( JNIEnv* env, jclass C, jlong closure, jint min, jint max )
{
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
di_initIter( &data->iter, data->dict, min, max );
makeIndex( data );
(void)di_firstWord( &data->iter );
}
DI_HEADER_END();
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_di_1destroy
( JNIEnv* env, jclass C, jlong closure )
{
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
#ifdef MEM_DEBUG
MemPoolCtx* mpool = data->mpool;
MemPoolCtx* mpool = data->globalState->mpool;
#endif
dict_unref( data->dict, env );
freeIndices( data );
@ -2464,6 +2484,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1destroy
XP_FREE( mpool, data );
}
DI_HEADER_END();
}
JNIEXPORT jint JNICALL
@ -2471,10 +2492,11 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1wordCount
(JNIEnv* env, jclass C, jlong closure )
{
jint result = 0;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
result = data->iter.nWords;
}
DI_HEADER_END();
return result;
}
@ -2483,7 +2505,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getCounts
(JNIEnv* env, jclass C, jlong closure )
{
jintArray result = NULL;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
DictIter iter;
di_initIter( &iter, data->dict, 0, MAX_COLS_DICT );
@ -2495,6 +2517,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getCounts
sizeof(lens.lens[0]) );
}
}
DI_HEADER_END();
return result;
}
@ -2503,7 +2526,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getPrefixes
( JNIEnv* env, jclass C, jlong closure )
{
jobjectArray result = NULL;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data && NULL != data->idata.prefixes ) {
result = makeStringArray( env, data->idata.count, NULL );
@ -2518,6 +2541,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getPrefixes
deleteLocalRef( env, jstr );
}
}
DI_HEADER_END();
return result;
}
@ -2526,7 +2550,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getIndices
( JNIEnv* env, jclass C, jlong closure )
{
jintArray jindices = NULL;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
XP_ASSERT( !!data->idata.indices );
XP_ASSERT( sizeof(jint) == sizeof(data->idata.indices[0]) );
@ -2534,6 +2558,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getIndices
(jint*)data->idata.indices,
sizeof(data->idata.indices[0]) );
}
DI_HEADER_END();
return jindices;
}
@ -2542,7 +2567,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1nthWord
( JNIEnv* env, jclass C, jlong closure, jint nn, jstring jdelim )
{
jstring result = NULL;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
if ( di_getNthWord( &data->iter, nn, data->depth, &data->idata ) ) {
XP_UCHAR buf[64];
@ -2555,6 +2580,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1nthWord
}
}
}
DI_HEADER_END();
return result;
}
@ -2578,7 +2604,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1strToTiles
( JNIEnv* env, jclass C, jlong closure, jstring jstr )
{
jobjectArray result = NULL;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
const char* str = (*env)->GetStringUTFChars( env, jstr, NULL );
FTData ftd = { .env = env, };
@ -2593,7 +2619,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1strToTiles
}
(*env)->ReleaseStringUTFChars( env, jstr, str );
DI_HEADER_END();
return result;
}
@ -2602,7 +2628,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getStartsWith
( JNIEnv* env, jclass C, jlong closure, jbyteArray jtiles )
{
jint result = -1;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
XP_U16 nTiles = (*env)->GetArrayLength( env, jtiles );
jbyte* tiles = (*env)->GetByteArrayElements( env, jtiles, NULL );
@ -2611,7 +2637,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getStartsWith
}
(*env)->ReleaseByteArrayElements( env, jtiles, tiles, 0 );
DI_HEADER_END();
return result;
}
@ -2620,13 +2646,12 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1tilesToStr
( JNIEnv* env, jclass C, jlong closure, jbyteArray jtiles, jstring jdelim )
{
jstring result = NULL;
DI_HEADER();
XP_UCHAR buf[64];
const XP_UCHAR* delim = NULL;
if ( !!jdelim ) {
delim = (*env)->GetStringUTFChars( env, jdelim, NULL );
}
DictIterData* data = (DictIterData*)closure;
XP_U16 nTiles = (*env)->GetArrayLength( env, jtiles );
jbyte* tiles = (*env)->GetByteArrayElements( env, jtiles, NULL );
@ -2642,7 +2667,7 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1tilesToStr
(*env)->ReleaseStringUTFChars( env, jdelim, delim );
}
(*env)->ReleaseByteArrayElements( env, jtiles, tiles, 0 );
DI_HEADER_END();
return result;
}
@ -2651,13 +2676,14 @@ Java_org_eehouse_android_xw4_jni_XwJNI_di_1getDesc
( JNIEnv* env, jclass C, jlong closure )
{
jstring result = NULL;
DictIterData* data = (DictIterData*)closure;
DI_HEADER();
if ( NULL != data ) {
const XP_UCHAR* disc = dict_getDesc( data->dict );
if ( NULL != disc && '\0' != disc[0] ) {
result = (*env)->NewStringUTF( env, disc );
}
}
DI_HEADER_END();
return result;
}
@ -2666,11 +2692,11 @@ freeIndices( DictIterData* data )
{
IndexData* idata = &data->idata;
if ( !!idata->prefixes ) {
XP_FREE( data->mpool, idata->prefixes );
XP_FREE( data->globalState->mpool, idata->prefixes );
idata->prefixes = NULL;
}
if( !!idata->indices ) {
XP_FREE( data->mpool, idata->indices );
XP_FREE( data->globalState->mpool, idata->indices );
idata->indices = NULL;
}
}
@ -2688,18 +2714,20 @@ makeIndex( DictIterData* data )
freeIndices( data );
IndexData* idata = &data->idata;
idata->prefixes = XP_MALLOC( data->mpool, count * data->depth
#ifdef MEM_DEBUG
MemPoolCtx* mpool = data->globalState->mpool;
#endif
idata->prefixes = XP_MALLOC( mpool, count * data->depth
* sizeof(*idata->prefixes) );
idata->indices = XP_MALLOC( data->mpool,
count * sizeof(*idata->indices) );
idata->indices = XP_MALLOC( mpool, count * sizeof(*idata->indices) );
idata->count = count;
di_makeIndex( &data->iter, data->depth, idata );
if ( 0 < idata->count ) {
idata->prefixes = XP_REALLOC( data->mpool, idata->prefixes,
idata->prefixes = XP_REALLOC( mpool, idata->prefixes,
idata->count * data->depth *
sizeof(*idata->prefixes) );
idata->indices = XP_REALLOC( data->mpool, idata->indices,
idata->indices = XP_REALLOC( mpool, idata->indices,
idata->count * sizeof(*idata->indices) );
} else {
freeIndices( data );