[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