00001 #ifndef DEF_INDEXCOMMANDLINE
00002 #define DEF_INDEXCOMMANDLINE
00003
00004 #include <iostream>
00005 #include <io.h>
00006
00007 namespace groupindex
00008 {
00009
00071 template <class CIndex, class CInterface>
00072 class IndexCommandLine
00073 {
00074
00075 protected:
00076
00077 typename CIndex::IndexRepresentation dr;
00078
00079
00080 std::fstream idxstream;
00081 std::fstream idxHeapStream;
00082
00083 CIndex* groupindex;
00084
00085 char indexfilename[1024];
00086 char* indexdirname;
00087 char* indexfname;
00088
00089
00090 char* heapfname;
00091
00092 int mismatches;
00093
00094 public:
00095
00096 int command(int argc, char** args);
00097
00098 IndexCommandLine();
00099
00100 int run();
00101
00102 };
00103
00104 template<class CIndex, class CInterface>
00105 int IndexCommandLine<CIndex, CInterface>::command(int argc, char** args)
00106 {
00107
00108 if (!stricmp(args[1],"CLOSE"))
00109 {
00110
00111 if (groupindex!=NULL)
00112 delete groupindex;
00113 return 0;
00114
00115 } else if (!stricmp(args[1],"OPEN")) {
00116
00117 if (argc<3)
00118 {
00119 std::cout<<"Specify index file (OPEN <indexfile>)\n";
00120 return 0;
00121 }
00122
00123 if (groupindex!=NULL)
00124 delete groupindex;
00125
00126 strcpy(indexfilename,args[2]);
00127
00128 if (strstr(indexfilename,"\\")==NULL && strstr(indexfilename,"/")==NULL)
00129 {
00130 indexfname = &indexfilename[0];
00131 indexdirname = &indexfilename[strlen(indexfilename)];
00132 } else {
00133
00134 int pos = strlen(indexfilename)-1;
00135 char c;
00136 while ((c = indexfilename[pos])!='\\' && c!='/')
00137 pos--;
00138 indexfilename[pos] = 0;
00139 indexdirname = indexfilename;
00140 indexfname = &indexfilename[pos];
00141 chdir(indexdirname);
00142 }
00143
00144 if (idxstream.is_open())
00145 idxstream.close();
00146
00147 #ifdef DEF_MULTIDIMGLIST
00148 if (idxHeapStream.is_open())
00149 idxHeapStream.close();
00150 #endif // DEF_MULTIDIMGLIST
00151
00152
00153 _finddata_t fileinfo;
00154
00155
00156 if (_findfirst(indexfname, &fileinfo)==-1)
00157 idxstream.open(indexfname,std::ios::binary|std::ios_base::in|std::ios_base::out|std::ios_base::trunc);
00158 else
00159 idxstream.open(indexfname,std::ios::binary|std::ios_base::in|std::ios_base::out);
00160
00161 #ifdef DEF_MULTIDIMGLIST
00162 if (strchr(indexfname, '.')!=NULL)
00163 strncpy(heapfname, indexfname, strcspn(indexfname, "."));
00164 else
00165 strcpy(heapfname, indexfname);
00166
00167 strcat(heapfname, ".hpf");
00168
00169 if (_findfirst(heapfname, &fileinfo)==-1)
00170 idxHeapStream.open(heapfname,std::ios::binary|std::ios_base::in|std::ios_base::out|std::ios_base::trunc);
00171 else
00172 idxHeapStream.open(heapfname,std::ios::binary|std::ios_base::in|std::ios_base::out);
00173
00174 dr.setHeapStream(idxHeapStream);
00175 #endif // DEF_MULTIDIMGLIST
00176
00177 if (!idxstream)
00178 {
00179 groupindex = new CIndex(dr);
00180 return 0;
00181 } else {
00182 groupindex = new CIndex(dr,idxstream);
00183 return 0;
00184 }
00185
00186
00187 } else if (!stricmp(args[1],"MISMATCHES")) {
00188
00189 if (argc<3)
00190 {
00191 std::cout<<"Missing parameters (MISMATCHES <n>)\n";
00192 return 0;
00193 }
00194 mismatches = atoi(args[2]);
00195 std::cout<<"Mismatches set to "<<mismatches<<".\n";
00196
00197 return 0;
00198
00199 } else if (!stricmp(args[1],"SEARCH")) {
00200
00201 if (groupindex==NULL)
00202 {
00203 std::cout<<"Use 'OPEN <indexfile>' to open index.\n";
00204 return 0;
00205 }
00206
00207
00208 if (argc<3)
00209 {
00210 std::cout<<"Missing parameters (SEARCH <query>)\n";
00211 return 0;
00212 }
00213
00214 typename std::set<ANSI_TYPENAME CIndex::IndexSet> query;
00215 CInterface::parseQuery(args[2], query);
00216
00217 typename std::set<ANSI_TYPENAME CIndex::IndexSet>::iterator m = query.begin();
00218
00219 typename CIndex::IndexSet* query_array;
00220 query_array = new typename CIndex::IndexSet[query.size()];
00221
00222
00223 int count = 0;
00224
00225 while (m != query.end()) {
00226
00227 query_array[count] = *m;
00228 ++m;
00229 count++;
00230
00231 }
00232
00233 std::cout<<"searching pattern...\n"; std::cout.flush();
00234 long hits = 0;
00235 ListTupel<ANSI_TYPENAME CIndex::IndexGroup >* results;
00236
00237 idxstream.seekg(0,std::ios::beg);
00238 try {
00239 hits = groupindex->search(query_array, query.size(), results, mismatches);
00240 } catch (IndexingException e) {
00241 std::cout<<e.what()<<std::endl;
00242 }
00243
00244 if (hits>0)
00245 std::cout<<"pattern found ..."<<std::endl;
00246 else
00247 std::cout<<"no match found ..."<<std::endl;
00248 std::cout.flush();
00249
00250 for (int l=0; l<hits; l++)
00251 {
00252 try {
00253 std::cout<<groupindex->getFileName(results[l].i).c_str()<<", "<<results[l].g<<", "<<results[l].credit<<std::endl;
00254 std::cout.flush();
00255 }
00256 catch(IndexingException e) {
00257 std::cout<<e.what()<<std::endl;
00258 }
00259 }
00260
00261 if (hits>0)
00262 delete[] results;
00263 delete[] query_array;
00264
00265 return 0;
00266
00267 } else if (!stricmp(args[1],"ADD")) {
00268
00269 if (groupindex== NULL)
00270 {
00271 std::cout<<"Use 'OPEN <indexfile>' to open index.\n";
00272 return 0;
00273 }
00274
00275
00276 if (argc<3)
00277 {
00278 std::cout<<"specify paramters (ADD <datafile1> .... <datafileN>)\n";
00279 return 0;
00280 }
00281
00282
00283 for (int i=2; i<argc; i++)
00284 CInterface::readDataFile(args[i], groupindex);
00285
00286
00287 std::ofstream ofs;
00288 char* tempfile;
00289 putenv("TMP=");
00290
00291 tempfile = tempnam(".\\",indexfname);
00292
00293 ofs.open(tempfile, std::ios::binary);
00294 ofs<<*groupindex;
00295 ofs.close();
00296 idxstream.close();
00297
00298 remove(indexfname);
00299 rename(&tempfile[2],indexfname);
00300
00301
00302 std::fstream new_idxstream;
00303
00304 new_idxstream.open(indexfname,std::ios::binary|std::ios_base::in|std::ios_base::out);
00305 if (!new_idxstream)
00306 {
00307 std::cout<<"Index File not found.\n";
00308 return 0;
00309 }
00310
00311 new_idxstream.close();
00312 idxstream.open(indexfname);
00313 groupindex = new CIndex(dr,idxstream);
00314
00315 std::cout<<"Files added and index saved in "<<indexfname<<".\n";
00316
00317 return 0;
00318
00319 } else if (!stricmp(args[1],"REMOVE")) {
00320
00321 if (groupindex==NULL)
00322 {
00323 std::cout<<"Use 'OPEN <indexfile>' to open index.\n";
00324 return 0;
00325 }
00326
00327 if (argc<3)
00328 {
00329 std::cout<<"Specify parameters (REMOVE <datafile1> .... <datafileN>)\n";
00330 return 0;
00331 }
00332
00333 for (int i=2; i<argc; i++)
00334 groupindex->remove(args[i]);
00335
00336
00337 std::ofstream ofs;
00338 char* tempfile;
00339 putenv("TMP=");
00340
00341 tempfile = tempnam(".\\",indexfname);
00342
00343 ofs.open(tempfile, std::ios::binary);
00344 ofs<<*groupindex;
00345 ofs.close();
00346 idxstream.close();
00347
00348 remove(indexfname);
00349 rename(&tempfile[2],indexfname);
00350
00351
00352 idxstream.open(indexfname,std::ios::binary);
00353
00354 if (!idxstream)
00355 {
00356 std::cout<<"Index File not found.\n";
00357 return 0;
00358 }
00359
00360 groupindex = new CIndex(dr,idxstream);
00361
00362 std::cout<<"Files removed and index saved in "<<indexfname<<".\n";
00363
00364 return 0;
00365
00366 } else if (!stricmp(args[1],"MERGE")) {
00367
00368 if (groupindex==NULL)
00369 {
00370 std::cout<<"Use 'OPEN <indexfile>' to open index.\n";
00371 return 0;
00372 }
00373
00374 if (argc<3)
00375 {
00376 std::cout<<"Syntax: MERGE <indexfile2> \n";
00377 return 0;
00378 }
00379
00380 groupindex->merge(args[2],MODE_MERGE_MAKE_UNIQUE);
00381
00382
00383
00384 std::ofstream ofs;
00385 char* tempfile;
00386 putenv("TMP=");
00387
00388 tempfile = tempnam(".\\",indexfname);
00389
00390 ofs.open(tempfile, std::ios::binary);
00391 ofs<<*groupindex;
00392 ofs.close();
00393 idxstream.close();
00394
00395 remove(indexfname);
00396 rename(&tempfile[2],indexfname);
00397
00398
00399 idxstream.open(indexfname,std::ios::binary);
00400 if (!idxstream)
00401 {
00402 std::cout<<"Index File not found.\n";
00403 return 0;
00404 }
00405
00406 groupindex = new CIndex(dr,idxstream);
00407
00408 std::cout<<"Index merged with Index "<<args[2]<<".\n";
00409
00410 return 0;
00411
00412 } else if (!stricmp(args[1],"LIST")) {
00413
00414 if (groupindex==NULL)
00415 {
00416 std::cout<<"Use 'OPEN <indexfile>' to open index.\n";
00417 return 0;
00418 }
00419
00420 std::set<std::string> names;
00421 groupindex->getFilenames(names);
00422
00423 std::set<std::string>::iterator it;
00424 for (it = names.begin(); it != names.end(); it++)
00425 {
00426 std::cout<<(*it).c_str()<<std::endl;
00427 }
00428 std::cout<<std::endl;
00429
00430 } else if (!stricmp(args[1],"OPERATE")) {
00431
00432 if (stricmp(args[2],"WITH") || stricmp(args[4],"ON") || stricmp(args[6],"TO"))
00433 {
00434 std::cout<<"Syntax: OPERATE WITH <groupfile> ON <datafile> TO <targetfile>"<<std::endl;
00435 return 0;
00436 }
00437
00438 typename CIndex::IndexGroup g;
00439 try {
00440 CInterface::readGroupFile(g,args[3]);
00441 } catch (IndexingException e) {
00442 std::cout<<e.what()<<std::endl;
00443 return 0;
00444 }
00445
00446 std::cout<<g<<std::endl;
00447 std::cout.flush();
00448
00449 typename std::set<ANSI_TYPENAME CIndex::IndexSet> objs;
00450
00451 CInterface::parseQuery(args[5],objs);
00452
00453 std::ofstream outstream;
00454 outstream.open(args[7]);
00455
00456 typename std::set<ANSI_TYPENAME CIndex::IndexSet>::iterator it = objs.begin();
00457
00458 for (; it!=objs.end(); ++it)
00459 {
00460 typename CIndex::IndexSet s = (*it);
00461 g *= s;
00462 std::ostream o_outstream(outstream.rdbuf());
00463 o_outstream<<s;
00464 }
00465
00466 outstream.close();
00467
00468
00469 } else if (!stricmp(args[1],"EXIT")) {
00470
00471 if (groupindex!=NULL)
00472 delete groupindex;
00473
00474 return -1;
00475
00476 } else {
00477
00478 std::cout<<"Specify parameters:"<<std::endl<<"SEARCH <query> IN <indexfile>"<<std::endl;
00479 std::cout<<"ADD <datafile1> ... <datafileN>\n";
00480 std::cout<<"REMOVE <datafile1> ... <datafileN>\n";
00481 std::cout<<"MERGE <indexfile2>\n";
00482 std::cout<<"EXIT\n";
00483 std::cout<<"LIST\n";
00484 std::cout<<"OPEN <indexfile>\n";
00485 std::cout<<"CLOSE\n";
00486 return 0;
00487
00488 }
00489
00490
00491 std::cout.flush();
00492
00493 return 0;
00494
00495 };
00496
00497 template<class CIndex, class CInterface>
00498 IndexCommandLine<CIndex, CInterface>::IndexCommandLine()
00499 {
00500
00501 groupindex = NULL;
00502 mismatches = 0;
00503
00504 dr.setHeapStream(idxHeapStream);
00505 }
00506
00507
00508 template<class CIndex, class CInterface>
00509 int IndexCommandLine<CIndex, CInterface>::run()
00510 {
00511
00512 bool end = false;
00513
00514 char** line_input = new char*[32];
00515 for (int k=0; k<32;k++)
00516 line_input[k] = new char[128];
00517 strcpy(line_input[0],"IndexCommandLine");
00518
00519 while (!end)
00520 {
00521 std::cout<<"> ";
00522
00523 int line_count = 1;
00524 bool line_end = false;
00525 std::cout.flush();
00526
00527 int len = 0;
00528 while (line_count<32 && !line_end)
00529 {
00530 std::cin>>line_input[line_count];
00531 len = strlen(line_input[line_count]);
00532
00533 int my_len;
00534 char buf[128];
00535 if (line_input[line_count][0]=='\"')
00536 {
00537 strcpy(line_input[line_count],&line_input[line_count][1]);
00538 do {
00539 std::cin>>buf;
00540 strcat(line_input[line_count]," ");
00541 strcat(line_input[line_count],buf);
00542 my_len = strlen(buf);
00543 len = strlen(line_input[line_count]);
00544 }
00545 while ( !(buf[my_len-1]=='\"' || (buf[my_len-2]=='\"' && buf[my_len-1]==';') ) );
00546 if (buf[my_len-1]=='\"')
00547 line_input[line_count][len-1] = 0;
00548 else if (buf[my_len-2]=='\"')
00549 line_input[line_count][len-2] = 0;
00550 }
00551 if (len==0 || line_input[line_count][len-1]==';')
00552 line_end = true;
00553
00554 line_count++;
00555
00556 }
00557
00558
00559 if (len==1)
00560 line_count--;
00561 else
00562 {
00563 int pos = len-1;
00564 while (pos>0 && line_input[line_count-1][pos]!=';')
00565 pos--;
00566 line_input[line_count-1][pos] = 0;
00567 }
00568
00569
00570
00571
00572
00573
00574 int result;
00575 if (line_count>0)
00576 try {
00577 result = command(line_count, &(line_input[0]));
00578 std::cout<<std::endl;
00579 std::cout.flush();
00580 } catch (IndexingException e) {
00581 std::cout<<e.what()<<std::endl;
00582 }
00583
00584
00585 if (result<0)
00586 return 0;
00587
00588 }
00589
00590 return 0;
00591
00592 }
00593
00594 }
00595
00596 #endif