00001
00002
00003
00004
00005
00006
00007 #include <string.h>
00008 #include <swmodule.h>
00009 #include <utilfuns.h>
00010 #include <regex.h>
00011 #include <swfilter.h>
00012 #include <versekey.h>
00013 #ifndef _MSC_VER
00014 #include <iostream.h>
00015 #endif
00016
00017 SWDisplay SWModule::rawdisp;
00018 void SWModule::nullPercent(char percent, void *percentUserData) {}
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 SWModule::SWModule(const char *imodname, const char *imoddesc, SWDisplay *idisp, char *imodtype, SWTextEncoding encoding, SWTextDirection direction, SWTextMarkup markup, const char* imodlang)
00032 {
00033 key = CreateKey();
00034 entrybuf = new char [1];
00035 *entrybuf = 0;
00036 config = &ownConfig;
00037 entrybufallocsize = 0;
00038 modname = 0;
00039 error = 0;
00040 moddesc = 0;
00041 modtype = 0;
00042 modlang = 0;
00043 this->encoding = encoding;
00044 this->direction = direction;
00045 this->markup = markup;
00046 entrySize= -1;
00047 disp = (idisp) ? idisp : &rawdisp;
00048 stdstr(&modname, imodname);
00049 stdstr(&moddesc, imoddesc);
00050 stdstr(&modtype, imodtype);
00051 stdstr(&modlang, imodlang);
00052 stripFilters = new FilterList();
00053 rawFilters = new FilterList();
00054 renderFilters = new FilterList();
00055 optionFilters = new FilterList();
00056 encodingFilters = new FilterList();
00057 skipConsecutiveLinks = true;
00058 procEntAttr = true;
00059 }
00060
00061
00062
00063
00064
00065
00066 SWModule::~SWModule()
00067 {
00068 if (entrybuf)
00069 delete [] entrybuf;
00070 if (modname)
00071 delete [] modname;
00072 if (moddesc)
00073 delete [] moddesc;
00074 if (modtype)
00075 delete [] modtype;
00076 if (modlang)
00077 delete [] modlang;
00078
00079 if (key) {
00080 if (!key->Persist())
00081 delete key;
00082 }
00083
00084 stripFilters->clear();
00085 rawFilters->clear();
00086 renderFilters->clear();
00087 optionFilters->clear();
00088 encodingFilters->clear();
00089 entryAttributes.clear();
00090
00091 delete stripFilters;
00092 delete rawFilters;
00093 delete renderFilters;
00094 delete optionFilters;
00095 delete encodingFilters;
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105 SWKey *SWModule::CreateKey()
00106 {
00107 return new SWKey();
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117 char SWModule::Error()
00118 {
00119 char retval = error;
00120
00121 error = 0;
00122 return retval;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 char *SWModule::Name(const char *imodname)
00136 {
00137 return stdstr(&modname, imodname);
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 char *SWModule::Description(const char *imoddesc)
00151 {
00152 return stdstr(&moddesc, imoddesc);
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 char *SWModule::Type(const char *imodtype)
00166 {
00167 return stdstr(&modtype, imodtype);
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 char SWModule::Direction(signed char newdir) {
00179 if (newdir != -1)
00180 direction = newdir;
00181 return direction;
00182 }
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 char SWModule::Encoding(signed char newenc) {
00193 if (newenc != -1)
00194 encoding = newenc;
00195 return encoding;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 char SWModule::Markup(signed char newmark) {
00207 if (newmark != -1)
00208 markup = newmark;
00209 return markup;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 char *SWModule::Lang(const char *imodlang)
00223 {
00224 return stdstr(&modlang, imodlang);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 SWDisplay *SWModule::Disp(SWDisplay *idisp)
00238 {
00239 if (idisp)
00240 disp = idisp;
00241
00242 return disp;
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252 char SWModule::Display()
00253 {
00254 disp->Display(*this);
00255 return 0;
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 char SWModule::SetKey(const SWKey &ikey) {
00269 return SetKey(&ikey);
00270 }
00271
00272 char SWModule::SetKey(const SWKey *ikey)
00273 {
00274 SWKey *oldKey = 0;
00275
00276 if (key) {
00277 if (!key->Persist())
00278 oldKey = key;
00279 }
00280
00281 if (!ikey->Persist()) {
00282 key = CreateKey();
00283 *key = *ikey;
00284 }
00285 else key = (SWKey *)ikey;
00286
00287 if (oldKey)
00288 delete oldKey;
00289
00290 return 0;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 const char *SWModule::KeyText(const char *ikeytext)
00304 {
00305 if (ikeytext)
00306 SetKey(ikeytext);
00307
00308 return *key;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 SWModule &SWModule::operator =(SW_POSITION p)
00321 {
00322 *key = p;
00323 char saveError = key->Error();
00324
00325 switch (p) {
00326 case POS_TOP:
00327 (*this)++;
00328 (*this)--;
00329 break;
00330
00331 case POS_BOTTOM:
00332 (*this)--;
00333 (*this)++;
00334 break;
00335 }
00336
00337 error = saveError;
00338 return *this;
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 SWModule &SWModule::operator +=(int increment)
00351 {
00352 (*key) += increment;
00353 error = key->Error();
00354
00355 return *this;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 SWModule &SWModule::operator -=(int increment)
00368 {
00369 (*key) -= increment;
00370 error = key->Error();
00371
00372 return *this;
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 ListKey &SWModule::Search(const char *istr, int searchType, int flags, SWKey *scope, bool *justCheckIfSupported, void (*percent)(char, void *), void *percentUserData)
00392 {
00393 SWKey *savekey = 0;
00394 SWKey *searchkey = 0;
00395 regex_t preg;
00396 SWKey textkey;
00397 char **words = 0;
00398 char *wordBuf = 0;
00399 int wordCount = 0;
00400 const char *sres;
00401 terminateSearch = false;
00402 char perc = 1;
00403 bool savePEA = isProcessEntryAttributes();
00404
00405 processEntryAttributes(false);
00406 listkey.ClearList();
00407
00408 if (!key->Persist()) {
00409 savekey = CreateKey();
00410 *savekey = *key;
00411 }
00412 else savekey = key;
00413
00414 searchkey = (scope)?scope->clone():(key->Persist())?key->clone():0;
00415 if (searchkey) {
00416 searchkey->Persist(1);
00417 SetKey(*searchkey);
00418 }
00419
00420 (*percent)(perc, percentUserData);
00421
00422
00423
00424 VerseKey *vkcheck = 0;
00425 #ifndef _WIN32_WCE
00426 try {
00427 #endif
00428 vkcheck = SWDYNAMIC_CAST(VerseKey, key);
00429 #ifndef _WIN32_WCE
00430 }
00431 catch (...) {}
00432 #endif
00433
00434
00435 *this = BOTTOM;
00436
00437 long highIndex = (vkcheck)?32300:key->Index();
00438 if (!highIndex)
00439 highIndex = 1;
00440 *this = TOP;
00441 if (searchType >= 0) {
00442 flags |=searchType|REG_NOSUB|REG_EXTENDED;
00443 regcomp(&preg, istr, flags);
00444 }
00445
00446 (*percent)(++perc, percentUserData);
00447 if (searchType == -2) {
00448 wordBuf = (char *)calloc(sizeof(char), strlen(istr) + 1);
00449 strcpy(wordBuf, istr);
00450 words = (char **)calloc(sizeof(char *), 10);
00451 int allocWords = 10;
00452 words[wordCount] = strtok(wordBuf, " ");
00453 while (words[wordCount]) {
00454 wordCount++;
00455 if (wordCount == allocWords) {
00456 allocWords+=10;
00457 words = (char **)realloc(words, sizeof(char *)*allocWords);
00458 }
00459 words[wordCount] = strtok(NULL, " ");
00460 }
00461 }
00462
00463 perc = 5;
00464 (*percent)(perc, percentUserData);
00465
00466 while (!Error() && !terminateSearch) {
00467
00468
00469 long mindex = 0;
00470 if (vkcheck)
00471 mindex = vkcheck->NewIndex();
00472 else mindex = key->Index();
00473 float per = (float)mindex / highIndex;
00474 per *= 93;
00475 per += 5;
00476 char newperc = (char)per;
00477
00478 if (newperc > perc) {
00479 perc = newperc;
00480 (*percent)(perc, percentUserData);
00481 }
00482 else if (newperc < perc) {
00483 #ifndef _MSC_VER
00484 cerr << "Serious error: new percentage complete is less than previous value\n";
00485 cerr << "using vk? " << ((vkcheck)?"yes":"no") << "\n";
00486 cerr << "index: " << ((vkcheck)?vkcheck->NewIndex():key->Index()) << "\n";
00487 cerr << "highIndex: " << highIndex << "\n";
00488 cerr << "newperc ==" << (int)newperc << "%" << "is smaller than\n";
00489 cerr << "perc == " << (int )perc << "% \n";
00490 #endif
00491 }
00492 if (searchType >= 0) {
00493 if (!regexec(&preg, StripText(), 0, 0, 0)) {
00494 textkey = KeyText();
00495 listkey << textkey;
00496 }
00497 }
00498 else {
00499 if (searchType == -1) {
00500 sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(StripText(), istr) : strstr(StripText(), istr);
00501 if (sres) {
00502 textkey = KeyText();
00503 listkey << textkey;
00504 }
00505 }
00506 if (searchType == -2) {
00507 int i;
00508 const char *stripBuf = StripText();
00509 for (i = 0; i < wordCount; i++) {
00510 sres = ((flags & REG_ICASE) == REG_ICASE) ? stristr(stripBuf, words[i]) : strstr(stripBuf, words[i]);
00511 if (!sres)
00512 break;
00513 }
00514 if (i == wordCount) {
00515 textkey = KeyText();
00516 listkey << textkey;
00517 }
00518
00519 }
00520 }
00521 (*this)++;
00522 }
00523 if (searchType >= 0)
00524 regfree(&preg);
00525
00526 if (searchType == -2) {
00527 free(words);
00528 free(wordBuf);
00529 }
00530
00531 SetKey(*savekey);
00532
00533 if (!savekey->Persist())
00534 delete savekey;
00535
00536 if (searchkey)
00537 delete searchkey;
00538
00539 listkey = TOP;
00540 processEntryAttributes(savePEA);
00541 (*percent)(100, percentUserData);
00542
00543 return listkey;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 const char *SWModule::StripText(char *buf, int len)
00557 {
00558 return RenderText(buf, len, false);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 const char *SWModule::RenderText(char *buf, int len, bool render) {
00571 entryAttributes.clear();
00572 char *tmpbuf = (buf) ? buf : getRawEntry();
00573 SWKey *key = 0;
00574 static char *null = "";
00575
00576 if (tmpbuf) {
00577 unsigned long size = (len < 0) ? ((getEntrySize()<0) ? strlen(tmpbuf) : getEntrySize()) * FILTERPAD : len;
00578 if (size > 0) {
00579 key = (SWKey *)*this;
00580
00581 optionFilter(tmpbuf, size, key);
00582
00583 if (render) {
00584 renderFilter(tmpbuf, size, key);
00585 encodingFilter(tmpbuf, size, key);
00586 }
00587 else stripFilter(tmpbuf, size, key);
00588 }
00589 }
00590 else {
00591 tmpbuf = null;
00592 }
00593
00594 return tmpbuf;
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 const char *SWModule::RenderText(SWKey *tmpKey)
00607 {
00608 SWKey *savekey;
00609 const char *retVal;
00610
00611 if (!key->Persist()) {
00612 savekey = CreateKey();
00613 *savekey = *key;
00614 }
00615 else savekey = key;
00616
00617 SetKey(*tmpKey);
00618
00619 retVal = RenderText();
00620
00621 SetKey(*savekey);
00622
00623 if (!savekey->Persist())
00624 delete savekey;
00625
00626 return retVal;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 const char *SWModule::StripText(SWKey *tmpKey)
00639 {
00640 SWKey *savekey;
00641 const char *retVal;
00642
00643 if (!key->Persist()) {
00644 savekey = CreateKey();
00645 *savekey = *key;
00646 }
00647 else savekey = key;
00648
00649 SetKey(*tmpKey);
00650
00651 retVal = StripText();
00652
00653 SetKey(*savekey);
00654
00655 if (!savekey->Persist())
00656 delete savekey;
00657
00658 return retVal;
00659 }
00660
00661
00662 SWModule::operator const char*() {
00663 return RenderText();
00664 }
00665
00666
00667 const char *SWModule::getConfigEntry(const char *key) const {
00668 ConfigEntMap::iterator it = config->find(key);
00669 return (it != config->end()) ? it->second.c_str() : 0;
00670 }
00671
00672
00673 void SWModule::setConfig(ConfigEntMap *config) {
00674 this->config = config;
00675 }