1 /******************************************************************************
2  *
3  *  flatapi.cpp -	This file contains an api usable by non-C++
4  *			environments
5  *
6  * $Id: flatapi.cpp 3561 2018-01-07 06:45:42Z greg.hellings $
7  *
8  * Copyright 2002-2014 CrossWire Bible Society (http://www.crosswire.org)
9  *	CrossWire Bible Society
10  *	P. O. Box 2528
11  *	Tempe, AZ  85280-2528
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * General Public License for more details.
21  *
22  */
23 
24 #include <iostream>
25 #include <vector>
26 #include <map>
27 
28 #include <swversion.h>
29 #include <swmgr.h>
30 #include <installmgr.h>
31 #include <remotetrans.h>
32 #include <versekey.h>
33 #include <treekeyidx.h>
34 #include <filemgr.h>
35 #include <swbuf.h>
36 #include <swlog.h>
37 #include <localemgr.h>
38 #include <utilstr.h>
39 #include "corba/orbitcpp/webmgr.hpp"
40 
41 extern "C" {
42 #include <flatapi.h>
43 }
44 
45 using sword::VerseKey;
46 using sword::SWVersion;
47 using sword::SWBuf;
48 using sword::TreeKeyIdx;
49 
50 
51 #define GETSWMGR(handle, failReturn) HandleSWMgr *hmgr = (HandleSWMgr *)handle; if (!hmgr) return failReturn; WebMgr *mgr = hmgr->mgr; if (!mgr) return failReturn;
52 
53 #define GETSWMODULE(handle, failReturn) HandleSWModule *hmod = (HandleSWModule *)handle; if (!hmod) return failReturn; SWModule *module = hmod->mod; if (!module) return failReturn;
54 
55 #define GETINSTMGR(handle, failReturn) HandleInstMgr *hinstmgr = (HandleInstMgr *)handle; if (!hinstmgr) return failReturn; InstallMgr *installMgr = hinstmgr->installMgr; if (!installMgr) return failReturn;
56 
57 namespace {
58 
59 
clearStringArray(const char *** stringArray)60 void clearStringArray(const char ***stringArray) {
61 	if (*stringArray) {
62 		for (int i = 0; true; ++i) {
63 			if ((*stringArray)[i]) {
64 				delete [] (*stringArray)[i];
65 			}
66 			else break;
67 		}
68 		free((*stringArray));
69 		(*stringArray) = 0;
70 	}
71 }
72 
73 
clearModInfoArray(org_crosswire_sword_ModInfo ** modInfo)74 void clearModInfoArray(org_crosswire_sword_ModInfo **modInfo) {
75 	if (*modInfo) {
76 		for (int i = 0; true; ++i) {
77 			if ((*modInfo)[i].name) {
78 				delete [] (*modInfo)[i].name;
79 				delete [] (*modInfo)[i].description;
80 				delete [] (*modInfo)[i].category;
81 				delete [] (*modInfo)[i].language;
82 				delete [] (*modInfo)[i].version;
83 				delete [] (*modInfo)[i].delta;
84 			}
85 			else break;
86 		}
87 		free((*modInfo));
88 		(*modInfo) = 0;
89 	}
90 }
91 
92 
93 struct pu {
94 	char last;
95 	org_crosswire_sword_SWModule_SearchCallback progressReporter;
init__anon5f9a22730111::pu96 	void init(org_crosswire_sword_SWModule_SearchCallback pr) { progressReporter = pr; last = 0; }
97 };
percentUpdate(char percent,void * userData)98 void percentUpdate(char percent, void *userData) {
99 	struct pu *p = (struct pu *)userData;
100 
101 	if (percent != p->last) {
102 		p->progressReporter((int)percent);
103 		p->last = percent;
104 	}
105 }
106 
107 
108 class MyStatusReporter : public StatusReporter {
109 public:
110 	unsigned long last;
111 	org_crosswire_sword_InstallMgr_StatusCallback statusReporter;
MyStatusReporter()112 	MyStatusReporter() : last(0), statusReporter(0) {}
init(org_crosswire_sword_InstallMgr_StatusCallback sr)113 	void init(org_crosswire_sword_InstallMgr_StatusCallback sr) { statusReporter = sr; last = 0xffffffff; }
114 
update(unsigned long totalBytes,unsigned long completedBytes)115     virtual void update(unsigned long totalBytes, unsigned long completedBytes) {
116 
117 		if (!statusReporter) return;
118 
119 		if (completedBytes != last) {
120 			statusReporter("update", totalBytes, completedBytes);
121 			last = completedBytes;
122         }
123 	}
124 
125 
preStatus(long totalBytes,long completedBytes,const char * message)126     virtual void preStatus(long totalBytes, long completedBytes, const char *message) {
127 
128 		if (!statusReporter) return;
129 
130 		statusReporter(message, totalBytes, completedBytes);
131 /*
132 		SWBuf output;
133 		output.setFormatted("[ Total Bytes: %ld; Completed Bytes: %ld", totalBytes, completedBytes);
134 		while (output.size() < 75) output += " ";
135 		output += "]";
136 //		cout << "\n" << output.c_str() << "\n ";
137 //		int p = (int)(74.0 * (double)completedBytes/totalBytes);
138 //		for (int i = 0; i < p; ++i) { cout << "="; }
139 //		cout << "\n\n" << message << "\n";
140 		last = 0;
141 */
142 	}
143 
144 };
145 
146 class HandleSWModule {
147 public:
148 	SWModule *mod;
149 	char *renderBuf;
150 	char *stripBuf;
151 	char *renderHeader;
152 	char *rawEntry;
153 	char *configEntry;
154 	struct pu peeuuu;
155 	org_crosswire_sword_SearchHit *searchHits;
156 	const char **entryAttributes;
157 	const char **parseKeyList;
158 	const char **keyChildren;
159 
HandleSWModule(SWModule * mod)160 	HandleSWModule(SWModule *mod) : searchHits(0), entryAttributes(0), parseKeyList(0), keyChildren(0) {
161 		this->mod = mod;
162 		this->renderBuf = 0;
163 		this->stripBuf = 0;
164 		this->renderHeader = 0;
165 		this->rawEntry = 0;
166 		this->configEntry = 0;
167 	}
~HandleSWModule()168 	~HandleSWModule() {
169 		delete [] renderBuf;
170 		delete [] stripBuf;
171 		delete [] renderHeader;
172 		delete [] rawEntry;
173 		delete [] configEntry;
174 		clearSearchHits();
175 		clearEntryAttributes();
176 		clearParseKeyList();
177 		clearKeyChildren();
178 	}
179 
clearSearchHits()180 	void clearSearchHits() {
181 		if (searchHits) {
182 			for (int i = 0; true; ++i) {
183 				if (searchHits[i].modName) {
184 					delete [] searchHits[i].key;
185 				}
186 				else break;
187 			}
188 			free(searchHits);
189 			searchHits = 0;
190 		}
191 	}
clearEntryAttributes()192 	void clearEntryAttributes() {
193 		clearStringArray(&entryAttributes);
194 	}
clearParseKeyList()195 	void clearParseKeyList() {
196 		clearStringArray(&parseKeyList);
197 	}
clearKeyChildren()198 	void clearKeyChildren() {
199 		clearStringArray(&keyChildren);
200 	}
201 };
202 
203 
204 class HandleSWMgr {
205 public:
206 	WebMgr *mgr;
207 	org_crosswire_sword_ModInfo *modInfo;
208 	std::map<SWModule *, HandleSWModule *> moduleHandles;
209 	SWBuf filterBuf;
210 	static const char **globalOptions;
211 	static const char **globalOptionValues;
212 	static const char **availableLocales;
213 
HandleSWMgr(WebMgr * mgr)214 	HandleSWMgr(WebMgr *mgr) {
215 		this->mgr = mgr;
216 		this->modInfo = 0;
217 	}
218 
clearModInfo()219 	void clearModInfo() {
220 		clearModInfoArray(&modInfo);
221 	}
222 
~HandleSWMgr()223 	~HandleSWMgr() {
224 		clearModInfo();
225 		for (std::map<SWModule *, HandleSWModule *>::iterator it = moduleHandles.begin(); it != moduleHandles.end(); ++it) {
226 			delete it->second;
227 		}
228 		delete mgr;
229 	}
230 
getModuleHandle(SWModule * mod)231 	HandleSWModule *getModuleHandle(SWModule *mod) {
232 		if (!mod) return 0;
233 		if (moduleHandles.find(mod) == moduleHandles.end()) {
234 			moduleHandles[mod] = new HandleSWModule(mod);
235 		}
236 		return moduleHandles[mod];
237 	}
238 
clearGlobalOptions()239 	static void clearGlobalOptions() {
240 		clearStringArray(&globalOptions);
241 	}
242 
clearGlobalOptionValues()243 	static void clearGlobalOptionValues() {
244 		clearStringArray(&globalOptionValues);
245 	}
246 
clearAvailableLocales()247 	static void clearAvailableLocales() {
248 		clearStringArray(&availableLocales);
249 	}
250 };
251 
252 
253 class HandleInstMgr {
254 public:
255 	static const char **remoteSources;
256 	InstallMgr *installMgr;
257 	org_crosswire_sword_ModInfo *modInfo;
258 	std::map<SWModule *, HandleSWModule *> moduleHandles;
259 
260 	MyStatusReporter statusReporter;
HandleInstMgr()261 	HandleInstMgr() : installMgr(0), modInfo(0) {}
HandleInstMgr(InstallMgr * mgr)262 	HandleInstMgr(InstallMgr *mgr) {
263 		this->installMgr = mgr;
264 		this->modInfo = 0;
265 	}
266 
~HandleInstMgr()267 	~HandleInstMgr() {
268 		clearModInfo();
269 		for (std::map<SWModule *, HandleSWModule *>::iterator it = moduleHandles.begin(); it != moduleHandles.end(); ++it) {
270 			delete it->second;
271 		}
272 		delete installMgr;
273 	}
274 
getModuleHandle(SWModule * mod)275 	HandleSWModule *getModuleHandle(SWModule *mod) {
276 		if (!mod) return 0;
277 		if (moduleHandles.find(mod) == moduleHandles.end()) {
278 			moduleHandles[mod] = new HandleSWModule(mod);
279 		}
280 		return moduleHandles[mod];
281 	}
282 
clearRemoteSources()283 	static void clearRemoteSources() {
284 		clearStringArray(&remoteSources);
285 	}
286 
clearModInfo()287 	void clearModInfo() {
288 		clearModInfoArray(&modInfo);
289 	}
290 };
291 
292 
293 
294 const char **HandleSWMgr::globalOptions = 0;
295 const char **HandleSWMgr::globalOptionValues = 0;
296 const char **HandleSWMgr::availableLocales = 0;
297 
298 const char **HandleInstMgr::remoteSources = 0;
299 
300 const char **tmpStringArrayRetVal = 0;
301 char *tmpStringRetVal = 0;
302 
303 class InitStatics {
304 public:
InitStatics()305 	InitStatics() {
306 
307 		HandleSWMgr::globalOptions = 0;
308 		HandleSWMgr::globalOptionValues = 0;
309 		HandleSWMgr::availableLocales = 0;
310 
311 		HandleInstMgr::remoteSources = 0;
312 	}
~InitStatics()313 	~InitStatics() {
314 
315 		HandleSWMgr::clearGlobalOptions();
316 		HandleSWMgr::clearGlobalOptionValues();
317 
318 		HandleInstMgr::clearRemoteSources();
319 
320 		clearStringArray(&tmpStringArrayRetVal);
321         sword::stdstr(&tmpStringRetVal, (const char *)0);
322 
323 	}
324 } _initStatics;
325 
326 
327 
328 }
329 
330 //
331 // SWLog methods
332 //
333 //
334 
org_crosswire_sword_SWlog_logError(const char * msg)335 void SWDLLEXPORT org_crosswire_sword_SWlog_logError(const char *msg) {
336 	SWLog::getSystemLog()->logError(msg);
337 }
338 
org_crosswire_sword_SWlog_logDebug(const char * msg)339 void SWDLLEXPORT org_crosswire_sword_SWlog_logDebug(const char *msg) {
340 	SWLog::getSystemLog()->logDebug(msg);
341 }
342 
org_crosswire_sword_SWlog_logWarning(const char * msg)343 void SWDLLEXPORT org_crosswire_sword_SWlog_logWarning(const char *msg) {
344 	SWLog::getSystemLog()->logWarning(msg);
345 }
346 
org_crosswire_sword_SWlog_logInformation(const char * msg)347 void SWDLLEXPORT org_crosswire_sword_SWlog_logInformation(const char *msg) {
348 	SWLog::getSystemLog()->logInformation(msg);
349 }
350 
org_crosswire_sword_SWlog_logTimedInformation(const char * msg)351 void SWDLLEXPORT org_crosswire_sword_SWlog_logTimedInformation(const char *msg) {
352 	SWLog::getSystemLog()->logTimedInformation(msg);
353 }
354 
355 
356 //
357 // SWModule methods
358 //
359 //
360 
361 /*
362  * Class:     org_crosswire_sword_SWModule
363  * Method:    terminateSearch
364  * Signature: ()V
365  */
org_crosswire_sword_SWModule_terminateSearch(SWHANDLE hSWModule)366 void SWDLLEXPORT org_crosswire_sword_SWModule_terminateSearch
367   (SWHANDLE hSWModule) {
368 
369 	GETSWMODULE(hSWModule, );
370 
371 	module->terminateSearch = true;
372 }
373 
374 /*
375  * Class:     org_crosswire_sword_SWModule
376  * Method:    search
377  * Signature: (Ljava/lang/String;IJLjava/lang/String;Lorg/crosswire/android/sword/SWModule/SearchProgressReporter;)[Lorg/crosswire/android/sword/SWModule/SearchHit;
378  */
org_crosswire_sword_SWModule_search(SWHANDLE hSWModule,const char * searchString,int searchType,long flags,const char * scope,org_crosswire_sword_SWModule_SearchCallback progressReporter)379 const struct org_crosswire_sword_SearchHit * SWDLLEXPORT org_crosswire_sword_SWModule_search
380   (SWHANDLE hSWModule, const char *searchString, int searchType, long flags, const char *scope, org_crosswire_sword_SWModule_SearchCallback progressReporter) {
381 
382 	GETSWMODULE(hSWModule, 0);
383 
384 	hmod->clearSearchHits();
385 
386 	sword::ListKey lscope;
387 	sword::ListKey result;
388 
389 
390 	hmod->peeuuu.init(progressReporter);
391 	if ((scope) && (strlen(scope)) > 0) {
392 		sword::SWKey *p = module->createKey();
393         	sword::VerseKey *parser = SWDYNAMIC_CAST(VerseKey, p);
394 	        if (!parser) {
395         		delete p;
396 	                parser = new VerseKey();
397 	        }
398 	        *parser = module->getKeyText();
399 		lscope = parser->parseVerseList(scope, *parser, true);
400 		result = module->search(searchString, searchType, flags, &lscope, 0, &percentUpdate, &(hmod->peeuuu));
401                 delete parser;
402 	}
403 	else	result = module->search(searchString, searchType, flags, 0, 0, &percentUpdate, &(hmod->peeuuu));
404 
405 	int count = 0;
406 	for (result = sword::TOP; !result.popError(); result++) count++;
407 
408 	// if we're sorted by score, let's re-sort by verse, because Java can always re-sort by score
409 	result = sword::TOP;
410 	if ((count) && (long)result.getElement()->userData)
411 		result.sort();
412 
413 	struct org_crosswire_sword_SearchHit *retVal = (struct org_crosswire_sword_SearchHit *)calloc(count+1, sizeof(struct org_crosswire_sword_SearchHit));
414 
415 	int i = 0;
416 	for (result = sword::TOP; !result.popError(); result++) {
417 		// don't alloc this; we have a persistent const char * in SWModule we can just reference
418 		retVal[i].modName = module->getName();
419 		stdstr(&(retVal[i].key), assureValidUTF8(result.getShortText()));
420 		retVal[i++].score = (long)result.getElement()->userData;
421 		// in case we limit count to a max number of hits
422 		if (i >= count) break;
423 	}
424 	hmod->searchHits = retVal;
425 	return retVal;
426 }
427 
428 /*
429  * Class:     org_crosswire_sword_SWModule
430  * Method:    error
431  * Signature: ()C
432  */
org_crosswire_sword_SWModule_popError(SWHANDLE hSWModule)433 char SWDLLEXPORT org_crosswire_sword_SWModule_popError
434   (SWHANDLE hSWModule) {
435 
436 	GETSWMODULE(hSWModule, -1);
437 
438 	return module->popError();
439 }
440 
441 /*
442  * Class:     org_crosswire_sword_SWModule
443  * Method:    getEntrySize
444  * Signature: ()J
445  */
org_crosswire_sword_SWModule_getEntrySize(SWHANDLE hSWModule)446 long SWDLLEXPORT org_crosswire_sword_SWModule_getEntrySize
447   (SWHANDLE hSWModule) {
448 
449 	GETSWMODULE(hSWModule, 0);
450 
451 	return module->getEntrySize();
452 }
453 
454 /*
455  * Class:     org_crosswire_sword_SWModule
456  * Method:    getEntryAttribute
457  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)[Ljava/lang/String;
458  */
org_crosswire_sword_SWModule_getEntryAttribute(SWHANDLE hSWModule,const char * level1,const char * level2,const char * level3,char filteredBool)459 const char ** SWDLLEXPORT org_crosswire_sword_SWModule_getEntryAttribute
460   (SWHANDLE hSWModule, const char *level1, const char *level2, const char *level3, char filteredBool) {
461 
462 	GETSWMODULE(hSWModule, 0);
463 
464 	hmod->clearEntryAttributes();
465 
466 	module->renderText();	// force parse
467 	std::vector<SWBuf> results;
468 
469 	sword::AttributeTypeList &entryAttribs = module->getEntryAttributes();
470 	sword::AttributeTypeList::iterator i1Start, i1End;
471 	sword::AttributeList::iterator i2Start, i2End;
472 	sword::AttributeValue::iterator i3Start, i3End;
473 
474 	if ((level1) && (*level1) && *level1 != '-') {
475 		i1Start = entryAttribs.find(level1);
476 		i1End = i1Start;
477 		if (i1End != entryAttribs.end())
478 			++i1End;
479 	}
480 	else {
481 		i1Start = entryAttribs.begin();
482 		i1End   = entryAttribs.end();
483 	}
484 	for (;i1Start != i1End; ++i1Start) {
485 		if (level1 && *level1 && *level1 == '-') {
486 			results.push_back(i1Start->first);
487 		}
488 		else {
489 			if (level2 && *level2 && *level2 != '-') {
490 				i2Start = i1Start->second.find(level2);
491 				i2End = i2Start;
492 				if (i2End != i1Start->second.end())
493 					++i2End;
494 			}
495 			else {
496 				i2Start = i1Start->second.begin();
497 				i2End   = i1Start->second.end();
498 			}
499 			for (;i2Start != i2End; ++i2Start) {
500 				if (level2 && *level2 && *level2 == '-') {
501 					results.push_back(i2Start->first);
502 				}
503 				else {
504 					// allow '-' to get all keys; allow '*' to get all key=value
505 					if (level3 && *level3 && *level3 != '-' && *level3 != '*') {
506 						i3Start = i2Start->second.find(level3);
507 						i3End = i3Start;
508 						if (i3End != i2Start->second.end())
509 							++i3End;
510 					}
511 					else {
512 						i3Start = i2Start->second.begin();
513 						i3End   = i2Start->second.end();
514 					}
515 					for (;i3Start != i3End; ++i3Start) {
516 						if (level3 && *level3 && *level3 == '-') {
517 							results.push_back(i3Start->first);
518 						}
519 						else if (level3 && *level3 && *level3 == '*') {
520 							results.push_back(i3Start->first + "=" + i3Start->second);
521 						}
522 						else {
523 							results.push_back(i3Start->second);
524 						}
525 					}
526 					if (i3Start != i3End)
527 						break;
528 				}
529 			}
530 			if (i2Start != i2End)
531 				break;
532 		}
533 	}
534 
535 	const char **retVal = (const char **)calloc(results.size()+1, sizeof(const char *));
536 	for (int i = 0; i < (int)results.size(); i++) {
537 		if (filteredBool) {
538 			stdstr((char **)&(retVal[i]), assureValidUTF8(module->renderText(results[i].c_str())));
539 		}
540 		else {
541 			stdstr((char **)&(retVal[i]), assureValidUTF8(results[i].c_str()));
542 		}
543 	}
544 
545 	hmod->entryAttributes = retVal;
546 	return retVal;
547 }
548 
549 /*
550  * Class:     org_crosswire_sword_SWModule
551  * Method:    parseKeyList
552  * Signature: (Ljava/lang/String;)[Ljava/lang/String;
553  */
org_crosswire_sword_SWModule_parseKeyList(SWHANDLE hSWModule,const char * keyText)554 const char ** SWDLLEXPORT org_crosswire_sword_SWModule_parseKeyList
555   (SWHANDLE hSWModule, const char *keyText) {
556 
557 	GETSWMODULE(hSWModule, 0);
558 
559 	hmod->clearParseKeyList();
560 
561 	sword::VerseKey *parser = dynamic_cast<VerseKey *>(module->getKey());
562 	const char **retVal = 0;
563 	if (parser) {
564 		sword::ListKey result;
565 		result = parser->parseVerseList(keyText, *parser, true);
566 		int count = 0;
567 		for (result = sword::TOP; !result.popError(); result++) {
568 			count++;
569 		}
570 		retVal = (const char **)calloc(count+1, sizeof(const char *));
571 		count = 0;
572 		for (result = sword::TOP; !result.popError(); result++) {
573 			stdstr((char **)&(retVal[count++]), assureValidUTF8(VerseKey(result).getOSISRef()));
574 		}
575 	}
576 	else	{
577 		retVal = (const char **)calloc(2, sizeof(const char *));
578 		stdstr((char **)&(retVal[0]), assureValidUTF8(keyText));
579 	}
580 
581 	hmod->parseKeyList = retVal;
582 	return retVal;
583 }
584 
585 /*
586  * Class:     org_crosswire_sword_SWModule
587  * Method:    setKeyText
588  * Signature: (Ljava/lang/String;)V
589  */
590 // Special values handled for VerseKey modules:
591 //	[+-][book|chapter]	- [de|in]crement by chapter or book
592 //	(e.g.	"+chapter" will increment the VerseKey 1 chapter)
593 //	[=][key]		- position absolutely and don't normalize
594 //	(e.g.	"jn.1.0" for John Chapter 1 intro; "jn.0.0" For Book of John Intro)
org_crosswire_sword_SWModule_setKeyText(SWHANDLE hSWModule,const char * keyText)595 void SWDLLEXPORT org_crosswire_sword_SWModule_setKeyText
596   (SWHANDLE hSWModule, const char *keyText) {
597 
598 	GETSWMODULE(hSWModule, );
599 
600 	sword::SWKey *key = module->getKey();
601 	sword::VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key);
602 	if (vkey) {
603 		if ((*keyText=='+' || *keyText=='-')) {
604 			if (!sword::stricmp(keyText+1, "book")) {
605 				vkey->setBook(vkey->getBook() + ((*keyText=='+')?1:-1));
606 				return;
607 			}
608 			else if (!sword::stricmp(keyText+1, "chapter")) {
609 				vkey->setChapter(vkey->getChapter() + ((*keyText=='+')?1:-1));
610 				return;
611 			}
612 		}
613 		else if (*keyText=='=') {
614 			vkey->setIntros(true);
615 			vkey->setAutoNormalize(false);
616 			vkey->setText(keyText+1);
617 			return;
618 		}
619 	}
620 
621 	module->setKey(keyText);
622 }
623 
624 /*
625  * Class:     org_crosswire_sword_SWModule
626  * Method:    getKeyText
627  * Signature: ()Ljava/lang/String;
628  */
org_crosswire_sword_SWModule_getKeyText(SWHANDLE hSWModule)629 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getKeyText
630   (SWHANDLE hSWModule) {
631 
632 	GETSWMODULE(hSWModule, 0);
633 
634 	return module->getKeyText();
635 }
636 
637 /*
638  * Class:     org_crosswire_sword_SWModule
639  * Method:    hasKeyChildren
640  * Signature: ()Z
641  */
org_crosswire_sword_SWModule_hasKeyChildren(SWHANDLE hSWModule)642 char SWDLLEXPORT org_crosswire_sword_SWModule_hasKeyChildren
643   (SWHANDLE hSWModule) {
644 
645 	GETSWMODULE(hSWModule, 0);
646 
647 	sword::SWKey *key = module->getKey();
648 	char retVal = 0;
649 
650 	TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
651 	if (tkey) {
652 		retVal = tkey->hasChildren()?1:0;
653 	}
654 	return retVal;
655 }
656 
657 /*
658  * Class:     org_crosswire_sword_SWModule
659  * Method:    getKeyChildren
660  * Signature: ()[Ljava/lang/String;
661  */
662 
663 // This method returns child nodes for a genbook,
664 // but has special handling if called on a VerseKey module:
665 //  [0..7] [testament, book, chapter, verse, chapterMax, verseMax, bookName, osisRef]
org_crosswire_sword_SWModule_getKeyChildren(SWHANDLE hSWModule)666 const char ** SWDLLEXPORT org_crosswire_sword_SWModule_getKeyChildren
667   (SWHANDLE hSWModule) {
668 
669 	GETSWMODULE(hSWModule, 0);
670 
671 	hmod->clearKeyChildren();
672 
673 	sword::SWKey *key = module->getKey();
674 	const char **retVal = 0;
675 	int count = 0;
676 
677 	sword::VerseKey *vkey = SWDYNAMIC_CAST(VerseKey, key);
678 	if (vkey) {
679 		retVal = (const char **)calloc(11, sizeof(const char *));
680 		SWBuf num;
681 		num.appendFormatted("%d", vkey->getTestament());
682 		stdstr((char **)&(retVal[0]), num.c_str());
683 		num = "";
684 		num.appendFormatted("%d", vkey->getBook());
685 		stdstr((char **)&(retVal[1]), num.c_str());
686 		num = "";
687 		num.appendFormatted("%d", vkey->getChapter());
688 		stdstr((char **)&(retVal[2]), num.c_str());
689 		num = "";
690 		num.appendFormatted("%d", vkey->getVerse());
691 		stdstr((char **)&(retVal[3]), num.c_str());
692 		num = "";
693 		num.appendFormatted("%d", vkey->getChapterMax());
694 		stdstr((char **)&(retVal[4]), num.c_str());
695 		num = "";
696 		num.appendFormatted("%d", vkey->getVerseMax());
697 		stdstr((char **)&(retVal[5]), num.c_str());
698 		stdstr((char **)&(retVal[6]), vkey->getBookName());
699 		stdstr((char **)&(retVal[7]), vkey->getOSISRef());
700 		stdstr((char **)&(retVal[8]), vkey->getShortText());
701 		stdstr((char **)&(retVal[9]), vkey->getBookAbbrev());
702 	}
703 	else {
704 		TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
705 		if (tkey) {
706 			if (tkey->firstChild()) {
707 				do {
708 					count++;
709 				}
710 				while (tkey->nextSibling());
711 				tkey->parent();
712 			}
713 			retVal = (const char **)calloc(count+1, sizeof(const char *));
714 			count = 0;
715 			if (tkey->firstChild()) {
716 				do {
717 					stdstr((char **)&(retVal[count++]), assureValidUTF8(tkey->getLocalName()));
718 				}
719 				while (tkey->nextSibling());
720 				tkey->parent();
721 			}
722 		}
723 	}
724 
725 	hmod->keyChildren = retVal;
726 	return retVal;
727 }
728 
729 /*
730  * Class:     org_crosswire_sword_SWModule
731  * Method:    getName
732  * Signature: ()Ljava/lang/String;
733  */
org_crosswire_sword_SWModule_getName(SWHANDLE hSWModule)734 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getName
735   (SWHANDLE hSWModule) {
736 
737 	GETSWMODULE(hSWModule, 0);
738 
739 	return module->getName();
740 }
741 
742 /*
743  * Class:     org_crosswire_sword_SWModule
744  * Method:    getDescription
745  * Signature: ()Ljava/lang/String;
746  */
org_crosswire_sword_SWModule_getDescription(SWHANDLE hSWModule)747 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getDescription
748   (SWHANDLE hSWModule) {
749 
750 	GETSWMODULE(hSWModule, 0);
751 
752 	return module->getDescription();
753 }
754 
755 /*
756  * Class:     org_crosswire_sword_SWModule
757  * Method:    getCategory
758  * Signature: ()Ljava/lang/String;
759  */
org_crosswire_sword_SWModule_getCategory(SWHANDLE hSWModule)760 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getCategory
761   (SWHANDLE hSWModule) {
762 
763 	static SWBuf type;
764 
765 	GETSWMODULE(hSWModule, 0);
766 
767 	type = module->getType();
768 	SWBuf cat = module->getConfigEntry("Category");
769 	if (cat.length() > 0)
770 		type = cat;
771 
772 	return type.c_str();
773 }
774 
775 /*
776  * Class:     org_crosswire_sword_SWModule
777  * Method:    getKeyParent
778  * Signature: ()Ljava/lang/String;
779  */
org_crosswire_sword_SWModule_getKeyParent(SWHANDLE hSWModule)780 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getKeyParent
781   (SWHANDLE hSWModule) {
782 
783 	static SWBuf retVal;
784 
785 	GETSWMODULE(hSWModule, 0);
786 
787 	sword::SWKey *key = module->getKey();
788 
789 	retVal = "";
790 
791 	TreeKeyIdx *tkey = SWDYNAMIC_CAST(TreeKeyIdx, key);
792 	if (tkey) {
793 		if (tkey->parent()) {
794 			retVal = tkey->getText();
795 		}
796 	}
797 	return assureValidUTF8(retVal.c_str());
798 }
799 
800 /*
801  * Class:     org_crosswire_sword_SWModule
802  * Method:    previous
803  * Signature: ()V
804  */
org_crosswire_sword_SWModule_previous(SWHANDLE hSWModule)805 void SWDLLEXPORT org_crosswire_sword_SWModule_previous
806   (SWHANDLE hSWModule) {
807 
808 	GETSWMODULE(hSWModule, );
809 
810 	module->decrement();
811 }
812 
813 
814 /*
815  * Class:     org_crosswire_sword_SWModule
816  * Method:    next
817  * Signature: ()V
818  */
org_crosswire_sword_SWModule_next(SWHANDLE hSWModule)819 void SWDLLEXPORT org_crosswire_sword_SWModule_next
820   (SWHANDLE hSWModule) {
821 
822 	GETSWMODULE(hSWModule, );
823 
824 	module->increment();
825 }
826 
827 
828 /*
829  * Class:     org_crosswire_sword_SWModule
830  * Method:    begin
831  * Signature: ()V
832  */
org_crosswire_sword_SWModule_begin(SWHANDLE hSWModule)833 void SWDLLEXPORT org_crosswire_sword_SWModule_begin
834   (SWHANDLE hSWModule) {
835 
836 	GETSWMODULE(hSWModule, );
837 
838 	module->setPosition(sword::TOP);
839 }
840 
841 
842 /*
843  * Class:     org_crosswire_sword_SWModule
844  * Method:    getStripText
845  * Signature: ()Ljava/lang/String;
846  */
org_crosswire_sword_SWModule_stripText(SWHANDLE hSWModule)847 const char * SWDLLEXPORT org_crosswire_sword_SWModule_stripText
848   (SWHANDLE hSWModule) {
849 
850 	GETSWMODULE(hSWModule, 0);
851 
852 	stdstr(&(hmod->stripBuf), assureValidUTF8((const char *)module->stripText()));
853 
854 	return hmod->stripBuf;
855 }
856 
857 /*
858  * Class:     org_crosswire_sword_SWModule
859  * Method:    getRenderText
860  * Signature: ()Ljava/lang/String;
861  */
org_crosswire_sword_SWModule_renderText(SWHANDLE hSWModule)862 const char * SWDLLEXPORT org_crosswire_sword_SWModule_renderText
863   (SWHANDLE hSWModule) {
864 
865 	GETSWMODULE(hSWModule, 0);
866 
867 	stdstr(&(hmod->renderBuf), assureValidUTF8((const char *)module->renderText().c_str()));
868 
869 	return hmod->renderBuf;
870 }
871 
872 /*
873  * Class:     org_crosswire_sword_SWModule
874  * Method:    getRenderHeader
875  * Signature: ()Ljava/lang/String;
876  */
877 // CSS styles associated with this text
org_crosswire_sword_SWModule_getRenderHeader(SWHANDLE hSWModule)878 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getRenderHeader
879   (SWHANDLE hSWModule) {
880 
881 	GETSWMODULE(hSWModule, 0);
882 
883 	stdstr(&(hmod->renderHeader), assureValidUTF8(((const char *)(module->getRenderHeader() ? module->getRenderHeader():""))));
884 
885 	return hmod->renderHeader;
886 }
887 
888 /*
889  * Class:     org_crosswire_sword_SWModule
890  * Method:    getRawEntry
891  * Signature: ()Ljava/lang/String;
892  */
org_crosswire_sword_SWModule_getRawEntry(SWHANDLE hSWModule)893 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getRawEntry
894   (SWHANDLE hSWModule) {
895 
896 	GETSWMODULE(hSWModule, 0);
897 
898 	stdstr(&(hmod->rawEntry), assureValidUTF8(((const char *)module->getRawEntry())));
899 
900 	return hmod->rawEntry;
901 }
902 
903 /*
904  * Class:     org_crosswire_sword_SWModule
905  * Method:    setRawEntry
906  * Signature: (Ljava/lang/String;)V
907  */
org_crosswire_sword_SWModule_setRawEntry(SWHANDLE hSWModule,const char * entryBuffer)908 void SWDLLEXPORT org_crosswire_sword_SWModule_setRawEntry
909   (SWHANDLE hSWModule, const char *entryBuffer) {
910 
911 	GETSWMODULE(hSWModule, );
912 
913 	module->setEntry(entryBuffer);
914 }
915 
916 
917 /*
918  * Class:     org_crosswire_sword_SWModule
919  * Method:    getConfigEntry
920  * Signature: (Ljava/lang/String;)Ljava/lang/String;
921  */
org_crosswire_sword_SWModule_getConfigEntry(SWHANDLE hSWModule,const char * key)922 const char * SWDLLEXPORT org_crosswire_sword_SWModule_getConfigEntry
923   (SWHANDLE hSWModule, const char *key) {
924 
925 	GETSWMODULE(hSWModule, 0);
926 
927 	stdstr(&(hmod->configEntry), (module->getConfigEntry(key) ? assureValidUTF8(module->getConfigEntry(key)).c_str() : 0));
928 
929 	return hmod->configEntry;
930 }
931 
932 /*
933  * Class:     org_crosswire_sword_SWModule
934  * Method:    deleteSearchFramework
935  * Signature: ()V
936  */
org_crosswire_sword_SWModule_deleteSearchFramework(SWHANDLE hSWModule)937 void SWDLLEXPORT org_crosswire_sword_SWModule_deleteSearchFramework
938   (SWHANDLE hSWModule) {
939 
940 	GETSWMODULE(hSWModule, );
941 
942 	module->deleteSearchFramework();
943 }
944 
945 
946 /*
947  * Class:     org_crosswire_sword_SWModule
948  * Method:    hasSearchFramework
949  * Signature: ()Z
950  */
org_crosswire_sword_SWModule_hasSearchFramework(SWHANDLE hSWModule)951 char SWDLLEXPORT org_crosswire_sword_SWModule_hasSearchFramework
952   (SWHANDLE hSWModule) {
953 
954 	GETSWMODULE(hSWModule, 0);
955 
956 	return (module->hasSearchFramework() && module->isSearchOptimallySupported("God", -4, 0, 0));
957 }
958 
959 
960 
961 
962 //
963 // SWMgr methods
964 //
965 //
966 
967 
968 /*
969  * Class:     org_crosswire_sword_SWMgr
970  * Method:    new
971  * Signature: ()V
972  */
org_crosswire_sword_SWMgr_new()973 SWHANDLE SWDLLEXPORT org_crosswire_sword_SWMgr_new() {
974 	SWConfig *sysConf = 0;
975 	return (SWHANDLE) new HandleSWMgr(new WebMgr(sysConf));
976 }
977 
978 /*
979  * Class:     org_crosswire_sword_SWMgr
980  * Method:    new
981  * Signature: ()V
982  */
org_crosswire_sword_SWMgr_newWithPath(const char * path)983 SWHANDLE SWDLLEXPORT org_crosswire_sword_SWMgr_newWithPath(const char *path) {
984 	SWBuf confPath = path;
985 	if (!confPath.endsWith("/")) confPath.append('/');
986 	SWBuf modsd = confPath + "mods.d";
987 	// be sure we have at least some config file already out there
988 	if (!FileMgr::existsFile(modsd.c_str())) {
989 		modsd.append("/globals.conf");
990 		FileMgr::createParent(modsd.c_str());
991 		SWConfig config(modsd.c_str());
992 		config["Globals"]["HiAndroid"] = "weeee";
993 		config.save();
994 	}
995 	SWBuf extraPath = confPath + "extraConfig.conf";
996 	bool exists = FileMgr::existsFile(extraPath.c_str());
997 SWLog::getSystemLog()->logDebug("libsword: extraConfig %s at path: %s", exists?"Exists":"Absent", extraPath.c_str());
998 
999 SWLog::getSystemLog()->logDebug("libsword: init() creating WebMgr using path: %s", path);
1000 	return (SWHANDLE) new HandleSWMgr(new WebMgr(confPath.c_str(), exists?extraPath.c_str():0));
1001 }
1002 
1003 
1004 /*
1005  * Class:     org_crosswire_sword_SWMgr
1006  * Method:    delete
1007  * Signature: ()V
1008  */
org_crosswire_sword_SWMgr_delete(SWHANDLE hSWMgr)1009 void SWDLLEXPORT org_crosswire_sword_SWMgr_delete(SWHANDLE hSWMgr) {
1010 	HandleSWMgr *hmgr = (HandleSWMgr *)hSWMgr;
1011 	if (hmgr) delete hmgr;
1012 }
1013 
1014 /*
1015  * Class:     org_crosswire_sword_SWMgr
1016  * Method:    version
1017  * Signature: ()Ljava/lang/String;
1018  */
org_crosswire_sword_SWMgr_version(SWHANDLE hSWMgr)1019 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_version
1020   (SWHANDLE hSWMgr) {
1021 	// we don't actually need an SWMgr to get version
1022 	static SWVersion v;
1023 	return v.currentVersion;
1024 }
1025 
1026 /*
1027  * Class:     org_crosswire_sword_SWMgr
1028  * Method:    getModInfoList
1029  * Signature: ()[Lorg/crosswire/android/sword/SWMgr/ModInfo;
1030  */
org_crosswire_sword_SWMgr_getModInfoList(SWHANDLE hSWMgr)1031 const struct org_crosswire_sword_ModInfo * SWDLLEXPORT org_crosswire_sword_SWMgr_getModInfoList
1032   (SWHANDLE hSWMgr) {
1033 
1034 	GETSWMGR(hSWMgr, 0);
1035 
1036 	sword::SWModule *module = 0;
1037 
1038 	hmgr->clearModInfo();
1039 
1040 	int size = 0;
1041 	for (sword::ModMap::iterator it = mgr->Modules.begin(); it != mgr->Modules.end(); ++it) {
1042 		if ((!(it->second->getConfigEntry("CipherKey"))) || (*(it->second->getConfigEntry("CipherKey"))))
1043 			size++;
1044 	}
1045 
1046 	struct org_crosswire_sword_ModInfo *milist = (struct org_crosswire_sword_ModInfo *)calloc(size+1, sizeof(struct org_crosswire_sword_ModInfo));
1047 	int i = 0;
1048 	for (sword::ModMap::iterator it = mgr->Modules.begin(); it != mgr->Modules.end(); ++it) {
1049 		module = it->second;
1050 		if ((!(module->getConfigEntry("CipherKey"))) || (*(module->getConfigEntry("CipherKey")))) {
1051 			SWBuf type = module->getType();
1052 			SWBuf cat = module->getConfigEntry("Category");
1053 			SWBuf version = module->getConfigEntry("Version");
1054 			if (cat.length() > 0) type = cat;
1055 			stdstr(&(milist[i].name), assureValidUTF8(module->getName()));
1056 			stdstr(&(milist[i].description), assureValidUTF8(module->getDescription()));
1057 			stdstr(&(milist[i].category), assureValidUTF8(type.c_str()));
1058 			stdstr(&(milist[i].language), assureValidUTF8(module->getLanguage()));
1059 			stdstr(&(milist[i].version), assureValidUTF8(version.c_str()));
1060 			stdstr(&(milist[i].delta), "");
1061 			if (++i >= size) break;
1062 		}
1063 	}
1064 	hmgr->modInfo = milist;
1065 	return milist;
1066 }
1067 
1068 /*
1069  * Class:     org_crosswire_sword_SWMgr
1070  * Method:    getModuleByName
1071  * Signature: (Ljava/lang/String;)Lorg/crosswire/android/sword/SWModule;
1072  */
org_crosswire_sword_SWMgr_getModuleByName(SWHANDLE hSWMgr,const char * moduleName)1073 SWHANDLE SWDLLEXPORT org_crosswire_sword_SWMgr_getModuleByName
1074   (SWHANDLE hSWMgr, const char *moduleName) {
1075 
1076 	GETSWMGR(hSWMgr, 0);
1077 
1078 	return (SWHANDLE)hmgr->getModuleHandle(hmgr->mgr->getModule(moduleName));
1079 }
1080 
1081 /*
1082  * Class:     org_crosswire_sword_SWMgr
1083  * Method:    getPrefixPath
1084  * Signature: ()Ljava/lang/String;
1085  */
org_crosswire_sword_SWMgr_getPrefixPath(SWHANDLE hSWMgr)1086 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_getPrefixPath
1087   (SWHANDLE hSWMgr) {
1088 
1089 	GETSWMGR(hSWMgr, 0);
1090 
1091 	return mgr->prefixPath;
1092 }
1093 
1094 /*
1095  * Class:     org_crosswire_sword_SWMgr
1096  * Method:    getConfigPath
1097  * Signature: ()Ljava/lang/String;
1098  */
org_crosswire_sword_SWMgr_getConfigPath(SWHANDLE hSWMgr)1099 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_getConfigPath
1100   (SWHANDLE hSWMgr) {
1101 
1102 	GETSWMGR(hSWMgr, 0);
1103 
1104 	return mgr->configPath;
1105 }
1106 
1107 /*
1108  * Class:     org_crosswire_sword_SWMgr
1109  * Method:    setGlobalOption
1110  * Signature: (Ljava/lang/String;Ljava/lang/String;)V
1111  */
org_crosswire_sword_SWMgr_setGlobalOption(SWHANDLE hSWMgr,const char * option,const char * value)1112 void SWDLLEXPORT org_crosswire_sword_SWMgr_setGlobalOption
1113   (SWHANDLE hSWMgr, const char *option, const char *value) {
1114 
1115 	GETSWMGR(hSWMgr, );
1116 	mgr->setGlobalOption(option, value);
1117 }
1118 
1119 /*
1120  * Class:     org_crosswire_sword_SWMgr
1121  * Method:    getGlobalOption
1122  * Signature: (Ljava/lang/String;)Ljava/lang/String;
1123  */
org_crosswire_sword_SWMgr_getGlobalOption(SWHANDLE hSWMgr,const char * option)1124 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_getGlobalOption
1125   (SWHANDLE hSWMgr, const char *option) {
1126 
1127 	GETSWMGR(hSWMgr, 0);
1128 
1129 	return mgr->getGlobalOption(option);
1130 }
1131 
1132 /*
1133  * Class:     org_crosswire_sword_SWMgr
1134  * Method:    getGlobalOptionTip
1135  * Signature: (Ljava/lang/String;)Ljava/lang/String;
1136  */
org_crosswire_sword_SWMgr_getGlobalOptionTip(SWHANDLE hSWMgr,const char * option)1137 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_getGlobalOptionTip
1138   (SWHANDLE hSWMgr, const char *option) {
1139 
1140 	GETSWMGR(hSWMgr, 0);
1141 
1142 	return mgr->getGlobalOptionTip(option);
1143 }
1144 
1145 /*
1146  * Class:     org_crosswire_sword_SWMgr
1147  * Method:    filterText
1148  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
1149  */
org_crosswire_sword_SWMgr_filterText(SWHANDLE hSWMgr,const char * filterName,const char * text)1150 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_filterText
1151   (SWHANDLE hSWMgr, const char *filterName, const char *text) {
1152 
1153 	GETSWMGR(hSWMgr, 0);
1154 
1155 	hmgr->filterBuf = text;
1156 
1157 // why was this in bindings/corba/omniorb?
1158 //	mgr->setGlobalOption("Greek Accents", "Off");
1159 
1160 	char errStatus = mgr->filterText(filterName, hmgr->filterBuf);
1161 	(void)errStatus;
1162 	return hmgr->filterBuf.c_str();
1163 }
1164 
1165 /*
1166  * Class:     org_crosswire_sword_SWMgr
1167  * Method:    getGlobalOptions
1168  * Signature: ()[Ljava/lang/String;
1169  */
org_crosswire_sword_SWMgr_getGlobalOptions(SWHANDLE hSWMgr)1170 const char ** SWDLLEXPORT org_crosswire_sword_SWMgr_getGlobalOptions
1171   (SWHANDLE hSWMgr) {
1172 
1173 	GETSWMGR(hSWMgr, 0);
1174 
1175 	const char **retVal;
1176 	hmgr->clearGlobalOptions();
1177 
1178 	sword::StringList options = mgr->getGlobalOptions();
1179 	int count = 0;
1180 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
1181 		count++;
1182 	}
1183 	retVal = (const char **)calloc(count+1, sizeof(const char *));
1184 	count = 0;
1185 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
1186 		stdstr((char **)&(retVal[count++]), it->c_str());
1187 	}
1188 
1189 	hmgr->globalOptions = retVal;
1190 	return retVal;
1191 }
1192 
1193 
1194 /*
1195  * Class:     org_crosswire_sword_SWConfig
1196  * Method:    getSections
1197  * Signature: ()[Ljava/lang/String;
1198  */
org_crosswire_sword_SWConfig_getSections(const char * confPath)1199 const char ** SWDLLEXPORT org_crosswire_sword_SWConfig_getSections
1200 		(const char *confPath) {
1201 
1202 	clearStringArray(&tmpStringArrayRetVal);
1203 	int count = 0;
1204 	const char **retVal = 0;
1205 	bool exists = FileMgr::existsFile(confPath);
1206 SWLog::getSystemLog()->logDebug("libsword: getConfigSections %s at path: %s", exists?"Exists":"Absent", confPath);
1207 	if (exists) {
1208 		SWConfig config(confPath);
1209         SectionMap::const_iterator sit;
1210 		for (sit = config.getSections().begin(); sit != config.getSections().end(); ++sit) {
1211 			count++;
1212 		}
1213         SWLog::getSystemLog()->logDebug("libsword: %d sections found in config", count);
1214         retVal = (const char **)calloc(count+1, sizeof(const char *));
1215 		count = 0;
1216 		for (sit = config.getSections().begin(); sit != config.getSections().end(); ++sit) {
1217 			stdstr((char **)&(retVal[count++]), assureValidUTF8(sit->first.c_str()));
1218 		}
1219 	}
1220     else {
1221         retVal = (const char **)calloc(1, sizeof(const char *));
1222     }
1223 
1224 	tmpStringArrayRetVal = retVal;
1225 	return retVal;
1226 }
1227 
1228 
1229 
1230 /*
1231  * Class:     org_crosswire_sword_SWConfig
1232  * Method:    getSectionKeys
1233  * Signature: (Ljava/lang/String;)[Ljava/lang/String;
1234  */
org_crosswire_sword_SWConfig_getSectionKeys(const char * confPath,const char * section)1235 const char ** SWDLLEXPORT org_crosswire_sword_SWConfig_getSectionKeys
1236 		(const char *confPath, const char *section) {
1237 
1238 	clearStringArray(&tmpStringArrayRetVal);
1239 	int count = 0;
1240 	const char **retVal = 0;
1241 	bool exists = FileMgr::existsFile(confPath);
1242 	if (exists) {
1243 		SWConfig config(confPath);
1244 		SectionMap::const_iterator sit = config.getSections().find(section);
1245 		if (sit != config.getSections().end()) {
1246 			ConfigEntMap::const_iterator it;
1247 			for (it = sit->second.begin(); it != sit->second.end(); ++it) {
1248 				count++;
1249 			}
1250 			retVal = (const char **)calloc(count+1, sizeof(const char *));
1251 			count = 0;
1252 			for (it = sit->second.begin(); it != sit->second.end(); ++it) {
1253 				stdstr((char **)&(retVal[count++]), assureValidUTF8(it->first.c_str()));
1254 			}
1255 		}
1256 		else {
1257 			retVal = (const char **)calloc(1, sizeof(const char *));
1258 		}
1259 	}
1260 	else {
1261 		retVal = (const char **)calloc(1, sizeof(const char *));
1262 	}
1263 
1264 	tmpStringArrayRetVal = retVal;
1265 	return retVal;
1266 }
1267 
1268 
1269 /*
1270  * Class:     org_crosswire_sword_SWConfig
1271  * Method:    getKeyValue
1272  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
1273  */
org_crosswire_sword_SWConfig_getKeyValue(const char * confPath,const char * section,const char * key)1274 const char * SWDLLEXPORT org_crosswire_sword_SWConfig_getKeyValue
1275 		(const char *confPath, const char *section, const char *key) {
1276 
1277 	stdstr(&tmpStringRetVal, 0);
1278 	bool exists = FileMgr::existsFile(confPath);
1279 	if (exists) {
1280 		SWConfig config(confPath);
1281 		SectionMap::const_iterator sit = config.getSections().find(section);
1282 		if (sit != config.getSections().end()) {
1283 			ConfigEntMap::const_iterator it = sit->second.find(key);
1284 			if (it != sit->second.end()) {
1285 				stdstr(&tmpStringRetVal, assureValidUTF8(it->second.c_str()));
1286 			}
1287 		}
1288 	}
1289 
1290 	return tmpStringRetVal;
1291 }
1292 
1293 
1294 /*
1295  * Class:     org_crosswire_sword_SWConfig
1296  * Method:    setKeyValue
1297  * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
1298  */
org_crosswire_sword_SWConfig_setKeyValue(const char * confPath,const char * section,const char * key,const char * value)1299 void SWDLLEXPORT org_crosswire_sword_SWConfig_setKeyValue
1300 		(const char *confPath, const char *section, const char *key, const char *value) {
1301 
1302 	SWConfig config(confPath);
1303 	config[section][key] = value;
1304 	config.save();
1305 }
1306 
1307 
1308 /*
1309  * Class:     org_crosswire_sword_SWConfig
1310  * Method:    augmentConfig
1311  * Signature: (Ljava/lang/String;)[Ljava/lang/String;
1312  */
org_crosswire_sword_SWConfig_augmentConfig(const char * confPath,const char * configBlob)1313 const char ** SWDLLEXPORT org_crosswire_sword_SWConfig_augmentConfig
1314 		(const char *confPath, const char *configBlob) {
1315 
1316 
1317 	clearStringArray(&tmpStringArrayRetVal);
1318 	const char **retVal = 0;
1319 	int count = 0;
1320 
1321 	SWBuf myBlob = configBlob;
1322 
1323 	SWConfig config(confPath);
1324 
1325 	FileMgr::removeFile(confPath);
1326 	FileDesc *fd = FileMgr::getSystemFileMgr()->open(confPath, FileMgr::CREAT|FileMgr::WRONLY, FileMgr::IREAD|FileMgr::IWRITE);
1327 	fd->getFd();
1328 	fd->write(myBlob.c_str(), myBlob.size());
1329 	FileMgr::getSystemFileMgr()->close(fd);
1330 
1331 	SWConfig newConfig(confPath);
1332 
1333 	config.augment(newConfig);
1334 	config.save();
1335 
1336 	SectionMap::const_iterator sit;
1337 	for (sit = newConfig.getSections().begin(); sit != newConfig.getSections().end(); ++sit) {
1338 		count++;
1339 	}
1340 	retVal = (const char **)calloc(count+1, sizeof(const char *));
1341 	count = 0;
1342 	for (sit = newConfig.getSections().begin(); sit != newConfig.getSections().end(); ++sit) {
1343 		stdstr((char **)&(retVal[count++]), assureValidUTF8(sit->first.c_str()));
1344 	}
1345 
1346 	tmpStringArrayRetVal = retVal;
1347 	return retVal;
1348 }
1349 
1350 
1351 /*
1352  * Class:     org_crosswire_sword_SWMgr
1353  * Method:    getGlobalOptionValues
1354  * Signature: (Ljava/lang/String;)[Ljava/lang/String;
1355  */
org_crosswire_sword_SWMgr_getGlobalOptionValues(SWHANDLE hSWMgr,const char * option)1356 const char ** SWDLLEXPORT org_crosswire_sword_SWMgr_getGlobalOptionValues
1357   (SWHANDLE hSWMgr, const char *option) {
1358 
1359 	GETSWMGR(hSWMgr, 0);
1360 
1361 	const char **retVal = 0;
1362 	hmgr->clearGlobalOptionValues();
1363 
1364 	sword::StringList options = mgr->getGlobalOptionValues(option);
1365 	int count = 0;
1366 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
1367 		count++;
1368 	}
1369 	retVal = (const char **)calloc(count+1, sizeof(const char *));
1370 	count = 0;
1371 	for (sword::StringList::iterator it = options.begin(); it != options.end(); ++it) {
1372 		stdstr((char **)&(retVal[count++]), it->c_str());
1373 	}
1374 
1375 	hmgr->globalOptionValues = retVal;
1376 	return retVal;
1377 }
1378 
1379 /*
1380  * Class:     org_crosswire_sword_SWMgr
1381  * Method:    setCipherKey
1382  * Signature: (Ljava/lang/String;Ljava/lang/String;)V
1383  */
org_crosswire_sword_SWMgr_setCipherKey(SWHANDLE hSWMgr,const char * modName,const char * key)1384 void SWDLLEXPORT org_crosswire_sword_SWMgr_setCipherKey
1385   (SWHANDLE hSWMgr, const char *modName, const char *key) {
1386 
1387 	GETSWMGR(hSWMgr, );
1388 
1389 	mgr->setCipherKey(modName, key);
1390 }
1391 
1392 /*
1393  * Class:     org_crosswire_sword_SWMgr
1394  * Method:    setJavascript
1395  * Signature: (Z)V
1396  */
org_crosswire_sword_SWMgr_setJavascript(SWHANDLE hSWMgr,char valueBool)1397 void SWDLLEXPORT org_crosswire_sword_SWMgr_setJavascript
1398   (SWHANDLE hSWMgr, char valueBool) {
1399 
1400 	GETSWMGR(hSWMgr, );
1401 
1402 	mgr->setJavascript(valueBool);
1403 }
1404 
1405 /*
1406  * Class:     org_crosswire_sword_SWMgr
1407  * Method:    getAvailableLocales
1408  * Signature: ()[Ljava/lang/String;
1409  */
org_crosswire_sword_SWMgr_getAvailableLocales(SWHANDLE hSWMgr)1410 const char ** SWDLLEXPORT org_crosswire_sword_SWMgr_getAvailableLocales
1411   (SWHANDLE hSWMgr) {
1412 
1413 	GETSWMGR(hSWMgr, 0);
1414 
1415 	hmgr->clearAvailableLocales();
1416 	sword::StringList localeNames = LocaleMgr::getSystemLocaleMgr()->getAvailableLocales();
1417 	const char **retVal = 0;
1418 	int count = 0;
1419 	for (sword::StringList::iterator it = localeNames.begin(); it != localeNames.end(); ++it) {
1420 		count++;
1421 	}
1422 	retVal = (const char **)calloc(count+1, sizeof(const char *));
1423 	count = 0;
1424 	for (sword::StringList::iterator it = localeNames.begin(); it != localeNames.end(); ++it) {
1425 		stdstr((char **)&(retVal[count++]), it->c_str());
1426 	}
1427 
1428 	hmgr->availableLocales = retVal;
1429 	return retVal;
1430 }
1431 
1432 /*
1433  * Class:     org_crosswire_sword_SWMgr
1434  * Method:    setDefaultLocale
1435  * Signature: (Ljava/lang/String;)V
1436  */
org_crosswire_sword_SWMgr_setDefaultLocale(SWHANDLE hSWMgr,const char * name)1437 void SWDLLEXPORT org_crosswire_sword_SWMgr_setDefaultLocale
1438   (SWHANDLE hSWMgr, const char *name) {
1439 
1440 	// we don't actually need an SWMgr instance for this
1441 	GETSWMGR(hSWMgr, );
1442 
1443 	LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName(name);
1444 }
1445 
1446 /*
1447  * Class:     org_crosswire_sword_SWMgr
1448  * Method:    translate
1449  * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
1450  */
org_crosswire_sword_SWMgr_translate(SWHANDLE hSWMgr,const char * text,const char * localeName)1451 const char * SWDLLEXPORT org_crosswire_sword_SWMgr_translate
1452   (SWHANDLE hSWMgr, const char *text, const char *localeName) {
1453 
1454 	GETSWMGR(hSWMgr, 0);
1455 
1456 	return LocaleMgr::getSystemLocaleMgr()->translate(text, localeName);
1457 }
1458 
1459 
1460 
1461 
1462 //
1463 // InstallMgr methods
1464 //
1465 //
1466 
1467 
1468 /*
1469  * Class:     org_crosswire_sword_InstallMgr
1470  * Method:    new
1471  * Signature: (Ljava/lang/String;Lorg/crosswire/android/sword/SWModule/SearchProgressReporter;)V
1472  */
org_crosswire_sword_InstallMgr_new(const char * baseDir,org_crosswire_sword_InstallMgr_StatusCallback statusReporter)1473 SWHANDLE SWDLLEXPORT org_crosswire_sword_InstallMgr_new
1474   (const char *baseDir, org_crosswire_sword_InstallMgr_StatusCallback statusReporter) {
1475 	SWBuf confPath = SWBuf(baseDir) + "/InstallMgr.conf";
1476 	// be sure we have at least some config file already out there
1477 	if (!FileMgr::existsFile(confPath.c_str())) {
1478 		FileMgr::createParent(confPath.c_str());
1479 //		remove(confPath.c_str());
1480 
1481 		SWConfig config(confPath.c_str());
1482 		config["General"]["PassiveFTP"] = "true";
1483 		config.save();
1484 	}
1485 	HandleInstMgr *hinstmgr = new HandleInstMgr();
1486 	hinstmgr->statusReporter.init(statusReporter);
1487 	hinstmgr->installMgr = new InstallMgr(baseDir, &(hinstmgr->statusReporter));
1488 	return (SWHANDLE) hinstmgr;
1489 }
1490 
1491 /*
1492  * Class:     org_crosswire_sword_InstallMgr
1493  * Method:    delete
1494  * Signature: ()V
1495  */
org_crosswire_sword_InstallMgr_delete(SWHANDLE hInstallMgr)1496 void SWDLLEXPORT org_crosswire_sword_InstallMgr_delete
1497   (SWHANDLE hInstallMgr) {
1498 	HandleInstMgr *hinstMgr = (HandleInstMgr *)hInstallMgr;
1499 	if (hinstMgr) delete hinstMgr;
1500 }
1501 
1502 /*
1503  * Class:     org_crosswire_sword_InstallMgr
1504  * Method:    setUserDisclaimerConfirmed
1505  * Signature: ()V
1506  */
org_crosswire_sword_InstallMgr_setUserDisclaimerConfirmed(SWHANDLE hInstallMgr)1507 void SWDLLEXPORT org_crosswire_sword_InstallMgr_setUserDisclaimerConfirmed
1508   (SWHANDLE hInstallMgr) {
1509 
1510 	GETINSTMGR(hInstallMgr, );
1511 
1512 	installMgr->setUserDisclaimerConfirmed(true);
1513 }
1514 
1515 /*
1516  * Class:     org_crosswire_sword_InstallMgr
1517  * Method:    syncConfig
1518  * Signature: ()I
1519  */
org_crosswire_sword_InstallMgr_syncConfig(SWHANDLE hInstallMgr)1520 int SWDLLEXPORT org_crosswire_sword_InstallMgr_syncConfig
1521   (SWHANDLE hInstallMgr) {
1522 
1523 	GETINSTMGR(hInstallMgr, -1);
1524 
1525 	return installMgr->refreshRemoteSourceConfiguration();
1526 }
1527 
1528 /*
1529  * Class:     org_crosswire_sword_InstallMgr
1530  * Method:    uninstallModule
1531  * Signature: (Lorg/crosswire/android/sword/SWMgr;Ljava/lang/String;)I
1532  */
org_crosswire_sword_InstallMgr_uninstallModule(SWHANDLE hInstallMgr,SWHANDLE hSWMgr_removeFrom,const char * modName)1533 int SWDLLEXPORT org_crosswire_sword_InstallMgr_uninstallModule
1534   (SWHANDLE hInstallMgr, SWHANDLE hSWMgr_removeFrom, const char *modName) {
1535 
1536 	GETINSTMGR(hInstallMgr, -1);
1537 	GETSWMGR(hSWMgr_removeFrom, -1);
1538 
1539 	SWModule *module;
1540 	ModMap::iterator it = mgr->Modules.find(modName);
1541 	if (it == mgr->Modules.end()) {
1542 		return -2;
1543 	}
1544 	module = it->second;
1545 	return installMgr->removeModule(mgr, module->getName());
1546 }
1547 
1548 /*
1549  * Class:     org_crosswire_sword_InstallMgr
1550  * Method:    getRemoteSources
1551  * Signature: ()[Ljava/lang/String;
1552  */
org_crosswire_sword_InstallMgr_getRemoteSources(SWHANDLE hInstallMgr)1553 const char ** SWDLLEXPORT org_crosswire_sword_InstallMgr_getRemoteSources
1554   (SWHANDLE hInstallMgr) {
1555 
1556 	GETINSTMGR(hInstallMgr, 0);
1557 
1558 	hinstmgr->clearRemoteSources();
1559 	sword::StringList vals = LocaleMgr::getSystemLocaleMgr()->getAvailableLocales();
1560 	const char **retVal = 0;
1561 	int count = 0;
1562 	for (InstallSourceMap::iterator it = installMgr->sources.begin(); it != installMgr->sources.end(); ++it) {
1563 		count++;
1564 	}
1565 	retVal = (const char **)calloc(count+1, sizeof(const char *));
1566 	count = 0;
1567 	for (InstallSourceMap::iterator it = installMgr->sources.begin(); it != installMgr->sources.end(); ++it) {
1568 		stdstr((char **)&(retVal[count++]), it->second->caption.c_str());
1569 	}
1570 
1571 	hinstmgr->remoteSources = retVal;
1572 	return retVal;
1573 }
1574 
1575 /*
1576  * Class:     org_crosswire_sword_InstallMgr
1577  * Method:    refreshRemoteSource
1578  * Signature: (Ljava/lang/String;)I
1579  */
org_crosswire_sword_InstallMgr_refreshRemoteSource(SWHANDLE hInstallMgr,const char * sourceName)1580 int SWDLLEXPORT org_crosswire_sword_InstallMgr_refreshRemoteSource
1581   (SWHANDLE hInstallMgr, const char *sourceName) {
1582 
1583 	GETINSTMGR(hInstallMgr, -1);
1584 
1585 	InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
1586 	if (source == installMgr->sources.end()) {
1587 		return -3;
1588 	}
1589 
1590 	return installMgr->refreshRemoteSource(source->second);
1591 }
1592 
1593 /*
1594  * Class:     org_crosswire_sword_InstallMgr
1595  * Method:    getRemoteModInfoList
1596  * Signature: (Lorg/crosswire/android/sword/SWMgr;Ljava/lang/String;)[Lorg/crosswire/android/sword/SWMgr/ModInfo;
1597  */
org_crosswire_sword_InstallMgr_getRemoteModInfoList(SWHANDLE hInstallMgr,SWHANDLE hSWMgr_deltaCompareTo,const char * sourceName)1598 const struct org_crosswire_sword_ModInfo * SWDLLEXPORT org_crosswire_sword_InstallMgr_getRemoteModInfoList
1599   (SWHANDLE hInstallMgr, SWHANDLE hSWMgr_deltaCompareTo, const char *sourceName) {
1600 
1601 	GETINSTMGR(hInstallMgr, 0);
1602 	GETSWMGR(hSWMgr_deltaCompareTo, 0);
1603 
1604 	struct org_crosswire_sword_ModInfo *retVal = 0;
1605 
1606 	hinstmgr->clearModInfo();
1607 
1608 	InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
1609 	if (source == installMgr->sources.end()) {
1610 		retVal = (struct org_crosswire_sword_ModInfo *)calloc(1, sizeof(struct org_crosswire_sword_ModInfo));
1611 		hinstmgr->modInfo = retVal;
1612 		return retVal;
1613 	}
1614 
1615 	std::map<SWModule *, int> modStats = installMgr->getModuleStatus(*mgr, *source->second->getMgr());
1616 
1617 	int size = 0;
1618 	for (std::map<SWModule *, int>::iterator it = modStats.begin(); it != modStats.end(); ++it) {
1619 		size++;
1620 	}
1621 	retVal = (struct org_crosswire_sword_ModInfo *)calloc(size+1, sizeof(struct org_crosswire_sword_ModInfo));
1622 	int i = 0;
1623 	for (std::map<SWModule *, int>::iterator it = modStats.begin(); it != modStats.end(); ++it) {
1624 		SWModule *module = it->first;
1625 		int status = it->second;
1626 
1627 		SWBuf version = module->getConfigEntry("Version");
1628 		SWBuf statusString = " ";
1629 		if (status & InstallMgr::MODSTAT_NEW) statusString = "*";
1630 		if (status & InstallMgr::MODSTAT_OLDER) statusString = "-";
1631 		if (status & InstallMgr::MODSTAT_UPDATED) statusString = "+";
1632 
1633 		SWBuf type = module->getType();
1634 		SWBuf cat = module->getConfigEntry("Category");
1635 		if (cat.length() > 0) type = cat;
1636 
1637 		stdstr(&(retVal[i].name), assureValidUTF8(module->getName()));
1638 		stdstr(&(retVal[i].description), assureValidUTF8(module->getDescription()));
1639 		stdstr(&(retVal[i].category), assureValidUTF8(type.c_str()));
1640 		stdstr(&(retVal[i].language), assureValidUTF8(module->getLanguage()));
1641 		stdstr(&(retVal[i].version), assureValidUTF8(version.c_str()));
1642 		stdstr(&(retVal[i++].delta), assureValidUTF8(statusString.c_str()));
1643 		if (i >= size) break;
1644 	}
1645 	hinstmgr->modInfo = retVal;
1646 	return retVal;
1647 }
1648 
1649 /*
1650  * Class:     org_crosswire_sword_InstallMgr
1651  * Method:    remoteInstallModule
1652  * Signature: (Lorg/crosswire/android/sword/SWMgr;Ljava/lang/String;Ljava/lang/String;)I
1653  */
org_crosswire_sword_InstallMgr_remoteInstallModule(SWHANDLE hInstallMgr_from,SWHANDLE hSWMgr_to,const char * sourceName,const char * modName)1654 int SWDLLEXPORT org_crosswire_sword_InstallMgr_remoteInstallModule
1655   (SWHANDLE hInstallMgr_from, SWHANDLE hSWMgr_to, const char *sourceName, const char *modName) {
1656 
1657 	GETINSTMGR(hInstallMgr_from, -1);
1658 	GETSWMGR(hSWMgr_to, -1);
1659 
1660 	InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
1661 
1662 	if (source == installMgr->sources.end()) {
1663 		return -3;
1664 	}
1665 
1666 	InstallSource *is = source->second;
1667 	SWMgr *rmgr = is->getMgr();
1668 	SWModule *module;
1669 
1670 	ModMap::iterator it = rmgr->Modules.find(modName);
1671 
1672 	if (it == rmgr->Modules.end()) {
1673 		return -4;
1674 	}
1675 
1676 	module = it->second;
1677 
1678 	int error = installMgr->installModule(mgr, 0, module->getName(), is);
1679 
1680 	return error;
1681 }
1682 
1683 /*
1684  * Class:     org_crosswire_sword_InstallMgr
1685  * Method:    getRemoteModuleByName
1686  * Signature: (Ljava/lang/String;Ljava/lang/String;)Lorg/crosswire/android/sword/SWModule;
1687  */
org_crosswire_sword_InstallMgr_getRemoteModuleByName(SWHANDLE hInstallMgr,const char * sourceName,const char * modName)1688 SWHANDLE SWDLLEXPORT org_crosswire_sword_InstallMgr_getRemoteModuleByName
1689   (SWHANDLE hInstallMgr, const char *sourceName, const char *modName) {
1690 
1691 	GETINSTMGR(hInstallMgr, 0);
1692 
1693 	InstallSourceMap::iterator source = installMgr->sources.find(sourceName);
1694 
1695 	if (source == installMgr->sources.end()) {
1696 		return 0;
1697 	}
1698 
1699 	SWMgr *mgr = source->second->getMgr();
1700 
1701 	sword::SWModule *module = mgr->getModule(modName);
1702 
1703 	if (!module) {
1704 		return 0;
1705 	}
1706 
1707 	return (SWHANDLE)hinstmgr->getModuleHandle(module);
1708 
1709 }
1710