[sword-svn] r2588 - in trunk: bindings/java-jni/jni include src/mgr src/utilfuns
scribe at crosswire.org
scribe at crosswire.org
Sat Nov 6 09:24:45 MST 2010
Author: scribe
Date: 2010-11-06 09:24:45 -0700 (Sat, 06 Nov 2010)
New Revision: 2588
Modified:
trunk/bindings/java-jni/jni/swordstub.cpp
trunk/include/ftplib.h
trunk/src/mgr/ftplibftpt.cpp
trunk/src/utilfuns/ftplib.c
Log:
Added buffer capture feature to ftplib and use this to store directly to an SWBuf instead of a tmp file
Released local references to Java utf8 strings generated in the loop returning search results. This allows GC and keeps from overstepping out 512 object limit in a jni stack
Modified: trunk/bindings/java-jni/jni/swordstub.cpp
===================================================================
--- trunk/bindings/java-jni/jni/swordstub.cpp 2010-11-04 21:18:33 UTC (rev 2587)
+++ trunk/bindings/java-jni/jni/swordstub.cpp 2010-11-06 16:24:45 UTC (rev 2588)
@@ -1117,7 +1117,7 @@
init();
- const int MAX_RETURN_COUNT = 200;
+ const int MAX_RETURN_COUNT = 999999;
const char *expression = env->GetStringUTFChars(expressionJS, NULL);
const char *scope = env->GetStringUTFChars(scopeJS, NULL);
@@ -1160,16 +1160,20 @@
result.sort();
int i = 0;
+ jstring modName = env->NewStringUTF(assureValidUTF8(module->Name()));
for (result = sword::TOP; !result.Error(); result++) {
jfieldID fieldID;
jobject searchHit = env->AllocObject(clazzSearchHit);
- fieldID = env->GetFieldID(clazzSearchHit, "modName", "Ljava/lang/String;"); env->SetObjectField(searchHit, fieldID, env->NewStringUTF(assureValidUTF8(module->Name())));
- fieldID = env->GetFieldID(clazzSearchHit, "key", "Ljava/lang/String;"); env->SetObjectField(searchHit, fieldID, env->NewStringUTF(assureValidUTF8((const char *)result)));
+ fieldID = env->GetFieldID(clazzSearchHit, "modName", "Ljava/lang/String;"); env->SetObjectField(searchHit, fieldID, modName);
+ jstring key = env->NewStringUTF(assureValidUTF8((const char *)result));
+ fieldID = env->GetFieldID(clazzSearchHit, "key", "Ljava/lang/String;"); env->SetObjectField(searchHit, fieldID, key);
+ env->DeleteLocalRef(key);
fieldID = env->GetFieldID(clazzSearchHit, "score", "J"); env->SetLongField(searchHit, fieldID, (long)result.getElement()->userData);
env->SetObjectArrayElement(ret, i++, searchHit);
- if (i > MAX_RETURN_COUNT) break;
+ env->DeleteLocalRef(searchHit);
+ if (i >= MAX_RETURN_COUNT) break;
}
}
Modified: trunk/include/ftplib.h
===================================================================
--- trunk/include/ftplib.h 2010-11-04 21:18:33 UTC (rev 2587)
+++ trunk/include/ftplib.h 2010-11-06 16:24:45 UTC (rev 2588)
@@ -57,6 +57,8 @@
#define FTPLIB_IDLETIME 3
#define FTPLIB_CALLBACKARG 4
#define FTPLIB_CALLBACKBYTES 5
+#define FTPLIB_CALLBACK_WRITER 6
+#define FTPLIB_CALLBACK_WRITERARG 7
#ifdef __cplusplus
extern "C" {
@@ -64,6 +66,7 @@
typedef struct NetBuf netbuf;
typedef int (*FtpCallback)(netbuf *nControl, int xfered, void *arg);
+typedef int (*FtpCallbackWriter)(netbuf *nControl, const void *buffer, size_t size, void *arg);
/* v1 compatibility stuff */
#if !defined(_FTPLIB_NO_COMPAT)
Modified: trunk/src/mgr/ftplibftpt.cpp
===================================================================
--- trunk/src/mgr/ftplibftpt.cpp 2010-11-04 21:18:33 UTC (rev 2587)
+++ trunk/src/mgr/ftplibftpt.cpp 2010-11-06 16:24:45 UTC (rev 2588)
@@ -40,6 +40,14 @@
bool *term;
};
+int my_swbufwriter(netbuf *nControl, void *buffer, size_t size, void *swbuf) {
+ SWBuf &output = *(SWBuf *)swbuf;
+ int s = output.size();
+ output.size(s+size);
+ memcpy(output.getRawData()+s, buffer, size);
+ return size;
+}
+
int my_fprogress(netbuf *nControl, int xfered, void *arg) {
if (arg) {
MyProgressData *pd = (MyProgressData *)arg;
@@ -85,6 +93,8 @@
if (ftpConnection == 0) {
SWLog::getSystemLog()->logDebug("connecting to host: %s...\n", host.c_str());
if (FtpConnect(host, &ftpConnection)) {
+ FtpOptions(FTPLIB_CONNMODE, (passive) ? FTPLIB_PASSIVE : FTPLIB_PORT, ftpConnection);
+
SWLog::getSystemLog()->logDebug("connected. logging in...\n");
if (FtpLogin(u.c_str(), p.c_str(), ftpConnection)) {
SWLog::getSystemLog()->logDebug("logged in.\n");
@@ -103,15 +113,7 @@
return retVal;
}
-// yeah yeah, I know I know. Compile with curl support if you don't like it
-#pragma GCC diagnostic ignored "-Wall"
-void my_tmpnam(char *tmpName) {
- tmpName = tmpnam(tmpName);
-}
-#pragma GCC diagnostic warning "-Wall"
-
-
char FTPLibFTPTransport::getURL(const char *destPath, const char *sourceURL, SWBuf *destBuf) {
char retVal = 0;
@@ -128,29 +130,22 @@
if (!destBuf) {
outFile = destPath;
}
- else {
-#ifdef ANDROID
- outFile = "/sdcard/sword/InstallMgr/swtmpbuf.out";
-#else
- char tmpName[128];
- my_tmpnam(tmpName);
- outFile = tmpName;
-#endif
- }
sourcePath << (6 + host.length()); // shift << "ftp://hostname";
- SWLog::getSystemLog()->logDebug("getting file %s to %s\n", sourcePath.c_str(), outFile.c_str());
- if (passive)
- FtpOptions(FTPLIB_CONNMODE, FTPLIB_PASSIVE, ftpConnection);
- else
- FtpOptions(FTPLIB_CONNMODE, FTPLIB_PORT, ftpConnection);
-
+ SWLog::getSystemLog()->logDebug("getting file %s to %s\n", sourcePath.c_str(), destBuf ? "*internal buffer*" : outFile.c_str());
struct MyProgressData pd;
pd.sr = statusReporter;
pd.term = &term;
pd.totalSize = 0;
- // !!!WDG also want to set callback options
+ if (destBuf) {
+ FtpOptions(FTPLIB_CALLBACK_WRITER, (long)&my_swbufwriter, ftpConnection);
+ FtpOptions(FTPLIB_CALLBACK_WRITERARG, (long)destBuf, ftpConnection);
+ }
+ else {
+ FtpOptions(FTPLIB_CALLBACK_WRITER, 0L, ftpConnection);
+ }
+
FtpOptions(FTPLIB_CALLBACK, (long)&my_fprogress, ftpConnection);
FtpOptions(FTPLIB_CALLBACKARG, (long)&pd, ftpConnection);
FtpOptions(FTPLIB_CALLBACKBYTES, (long)2048, ftpConnection);
@@ -159,31 +154,17 @@
// SWLog::getSystemLog()->logDebug("getting test directory %s\n", sourcePath.c_str());
// FtpDir(NULL, sourcePath, ftpConnection);
SWLog::getSystemLog()->logDebug("getting real directory %s\n", sourcePath.c_str());
- retVal = FtpDir(outFile.c_str(), sourcePath, ftpConnection) - 1;
- SWLog::getSystemLog()->logDebug("got real directory %s to %s\n", sourcePath.c_str(), outFile.c_str());
+ retVal = FtpDir(destBuf ? 0 : outFile.c_str(), sourcePath, ftpConnection) - 1;
+ SWLog::getSystemLog()->logDebug("got real directory %s to %s\n", sourcePath.c_str(), destBuf ? "*internal buffer*" : outFile.c_str());
}
else {
SWLog::getSystemLog()->logDebug("getting file %s\n", sourcePath.c_str());
int size;
FtpSize(sourcePath, &size, FTPLIB_IMAGE, ftpConnection);
pd.totalSize = size;
- retVal = FtpGet(outFile.c_str(), sourcePath, FTPLIB_IMAGE, ftpConnection) - 1;
+ retVal = FtpGet(destBuf ? 0 : outFile.c_str(), sourcePath, FTPLIB_IMAGE, ftpConnection) - 1;
}
- // Is there a way to FTPGet directly to a buffer?
- // If not, we probably want to add x-platform way to open a tmp file with FileMgr
- // Currently outFile is set to tmpFile above sortof unsafe
- if (destBuf) {
- SWLog::getSystemLog()->logDebug("filling destBuf\n");
- FileDesc *fd = FileMgr::getSystemFileMgr()->open(outFile.c_str(), FileMgr::RDONLY);
- long size = fd->seek(0, SEEK_END);
- fd->seek(0, SEEK_SET);
- destBuf->size(size);
- fd->read(destBuf->getRawData(), size);
- FileMgr::getSystemFileMgr()->close(fd);
- FileMgr::removeFile(outFile.c_str());
- }
-
SWLog::getSystemLog()->logDebug("FTPLibFTPTransport - returning: %d\n", retVal);
return retVal;
}
Modified: trunk/src/utilfuns/ftplib.c
===================================================================
--- trunk/src/utilfuns/ftplib.c 2010-11-04 21:18:33 UTC (rev 2587)
+++ trunk/src/utilfuns/ftplib.c 2010-11-06 16:24:45 UTC (rev 2588)
@@ -126,7 +126,9 @@
int cmode;
struct timeval idletime;
FtpCallback idlecb;
+ FtpCallbackWriter writercb;
void *idlearg;
+ void *writerarg;
int xfered;
int cbbytes;
int xfered1;
@@ -569,8 +571,10 @@
ctrl->ctrl = NULL;
ctrl->cmode = FTPLIB_DEFMODE;
ctrl->idlecb = NULL;
+ ctrl->writercb = NULL;
ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0;
ctrl->idlearg = NULL;
+ ctrl->writerarg = NULL;
ctrl->xfered = 0;
ctrl->xfered1 = 0;
ctrl->cbbytes = 0;
@@ -607,6 +611,10 @@
nControl->idlecb = (FtpCallback) val;
rv = 1;
break;
+ case FTPLIB_CALLBACK_WRITER:
+ nControl->writercb = (FtpCallbackWriter) val;
+ rv = 1;
+ break;
case FTPLIB_IDLETIME:
v = (int) val;
rv = 1;
@@ -617,6 +625,10 @@
rv = 1;
nControl->idlearg = (void *) val;
break;
+ case FTPLIB_CALLBACK_WRITERARG:
+ rv = 1;
+ nControl->writerarg = (void *) val;
+ break;
case FTPLIB_CALLBACKBYTES:
rv = 1;
nControl->cbbytes = (int) val;
@@ -807,6 +819,7 @@
ctrl->dir = dir;
ctrl->idletime = nControl->idletime;
ctrl->idlearg = nControl->idlearg;
+ ctrl->writerarg = nControl->writerarg;
ctrl->xfered = 0;
ctrl->xfered1 = 0;
ctrl->cbbytes = nControl->cbbytes;
@@ -814,6 +827,7 @@
ctrl->idlecb = nControl->idlecb;
else
ctrl->idlecb = NULL;
+ ctrl->writercb = nControl->writercb;
*nData = ctrl;
return 1;
}
@@ -1203,6 +1217,7 @@
FILE *local = NULL;
netbuf *nData;
int rv=1;
+ int writeResult = 0;
if (localfile != NULL)
{
@@ -1237,13 +1252,15 @@
}
else
{
- while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0)
- if (fwrite(dbuf, 1, l, local) <= 0)
+ while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) {
+ writeResult = (nData->writercb) ? nData->writercb(nData, dbuf, l, nData->writerarg) : fwrite(dbuf, 1, l, local);
+ if (writeResult <= 0)
{
- perror("localfile write");
+ perror("localstore write");
rv = 0;
break;
}
+ }
}
free(dbuf);
fflush(local);
More information about the sword-cvs
mailing list