#include <RioExplorer.h>
Public Member Functions | |
bool | getMd5Sum (char *, char *, bool=false) |
getMd5sum obtém o md5 checksum do arquivo objectName e armazena em md5sum; armazena NULL caso objectName seja um diretório ou a operação falhe; retorna true se a operação for realizada com sucesso, e false caso contrário. | |
bool | updateCache () |
This method ensures that the cache, if existant, is fully updated. | |
void | copyCache (RioMd5 *) |
copyCache makes md5Cache equal as srcMd5.md5Cache, if this instance of RioMd5 was created with cache; used to load cache from another cache | |
bool | importData (QString, CRioSession *) |
importData gets data from all files in srcDirectory and stores on md5Cache if RioMd5 was created with cache; used to load cache from remote md5 data | |
RioMd5 (RioExplorer *, CRioSession *) | |
RioMd5 is the class that is responsible for returning the md5 checksums for both local and remote files. | |
RioMd5 (RioExplorer *, CRioSession *, char *) | |
~RioMd5 () | |
Private Member Functions | |
char * | calculateMD5 (const char *, char *) |
void | loadCache (QString, vector< QDomElement > &) |
loadCache carrega todos os itens armazenados na cache do diretório src e de todos os seus subdiretórios no vetor md5Cache. | |
Private Attributes | |
RioExplorer * | parent |
CRioSession * | md5Session |
QString | srcDirectory |
vector< QDomElement > | md5Cache |
QString | MD5CACHEFILE |
Definition at line 228 of file RioExplorer.h.
RioMd5::RioMd5 | ( | RioExplorer * | explorer, | |
CRioSession * | session | |||
) |
RioMd5 is the class that is responsible for returning the md5 checksums for both local and remote files.
It may or may not load previously calculated checksums from am XML cache located at a local directory. //continue
Definition at line 3287 of file RioExplorer.cpp.
03288 { 03289 parent = explorer; 03290 md5Session = session; 03291 }
RioMd5::RioMd5 | ( | RioExplorer * | explorer, | |
CRioSession * | session, | |||
char * | src | |||
) |
Definition at line 3293 of file RioExplorer.cpp.
03294 { 03295 parent = explorer; 03296 md5Session = session; 03297 srcDirectory = QString( src ); 03298 MD5CACHEFILE = explorer->md5CacheFile(); 03299 loadCache( srcDirectory , md5Cache ); 03300 }
RioMd5::~RioMd5 | ( | ) |
Definition at line 3302 of file RioExplorer.cpp.
03303 { 03304 if( srcDirectory.isNull() ) return; //RioMd5 created without loading cache 03305 03306 #ifdef RIO_DEBUG2 03307 RioErr << "Destroying cache for " << srcDirectory.latin1() << endl; 03308 #endif 03309 //this element will store directory elements; each of these elements will 03310 //be children of the root elememnt and will contain the tag elements that 03311 //will be stored to the XML files on the respective directory 03312 QDomDocument doc( "document" ); 03313 QDomElement root = doc.createElement( "root" ); 03314 doc.appendChild( root ); 03315 03316 vector<QDomElement>::iterator elemIt; 03317 for( elemIt = md5Cache.begin(); elemIt != md5Cache.end(); elemIt++ ) 03318 { 03319 //getting directory 03320 QString dir = (*elemIt).attribute( "name" ).copy(); 03321 if( dir.findRev( '/' ) == -1 ) 03322 dir = ""; 03323 else 03324 dir.truncate( dir.findRev( '/' ) ); //getting directory 03325 03326 //getting name 03327 QString newName = (*elemIt).attribute( "name" ); 03328 if( dir != "" ) 03329 newName.remove( 0, dir.length() + 1 ); 03330 (*elemIt).setAttribute( "name", newName ); 03331 03332 //checking if the directory has already being added to the document 03333 bool found = false; 03334 QDomNode node = root.firstChild(); 03335 while( !node.isNull() && !found ) 03336 { 03337 if( node.isElement() ) 03338 { 03339 QDomElement elem = node.toElement(); 03340 if( ( elem.attribute( "dir" ) == dir ) ) //case positive 03341 { 03342 elem.appendChild( *elemIt ); 03343 found = true; 03344 } 03345 } 03346 node = node.nextSibling(); 03347 } 03348 if( !found ) //case negative 03349 { 03350 QDomElement newDir = doc.createElement( "root" ); 03351 newDir.setAttribute( "dir", dir ); 03352 newDir.appendChild( *elemIt ); //adding tag to directory 03353 root.appendChild( newDir ); //adding directory to main document 03354 } 03355 } 03356 03357 QDomNode exportNode = root.firstChild(); 03358 while( !exportNode.isNull() ) 03359 { 03360 //constructing XML file path 03361 QString fileOutput = exportNode.toElement().attribute( "dir" ).copy(); 03362 if( fileOutput == "" ) 03363 fileOutput = srcDirectory; 03364 else 03365 fileOutput = srcDirectory + '/' + fileOutput; 03366 fileOutput += '/'; 03367 fileOutput += MD5CACHEFILE; 03368 03369 #ifdef RIO_DEBUG2 03370 RioErr << "Exporting node to file: " << fileOutput.latin1() << endl; 03371 #endif 03372 03373 //root element can't contain attributes 03374 exportNode.toElement().removeAttribute( "dir" ); 03375 QFile file( fileOutput ); 03376 if( file.exists() && !file.remove() ) 03377 { 03378 #ifdef RIO_DEBUG2 03379 RioErr << "Couldn't reset file " << fileOutput.latin1() << endl; 03380 #endif 03381 03382 exportNode = exportNode.nextSibling(); 03383 continue; 03384 } 03385 file.open( IO_ReadWrite ); 03386 QTextStream stream( &file ); 03387 exportNode.save( stream, 0 ); 03388 03389 exportNode = exportNode.nextSibling(); 03390 } 03391 }
char * RioMd5::calculateMD5 | ( | const char * | filename, | |
char * | buf | |||
) | [private] |
Definition at line 3835 of file RioExplorer.cpp.
03836 { 03837 MD5_CTX state; 03838 03839 // Tamanho máximo do arquivo a ser lido 03840 unsigned int size = UINT_MAX; 03841 unsigned char digest[16]; 03842 char hex[17] = "0123456789abcdef"; 03843 char temp[100]; 03844 char *m; 03845 int fd; 03846 int di = 0; 03847 int rc; 03848 struct stat st; 03849 03850 fd = open( filename, O_RDONLY ); 03851 MD5_Init( &state ); 03852 03853 if( fstat( fd, &st ) == -1 ) 03854 { 03855 close( fd ); 03856 if( buf ) 03857 strcpy( buf, "0" ); 03858 else 03859 buf = strdup( "0" ); 03860 return buf; 03861 } 03862 03863 if( (unsigned int) st.st_size < size ) 03864 size = st.st_size; 03865 03866 if( ( m = (char *) mmap( 03867 (void *) 0, size, PROT_READ, MAP_PRIVATE, fd, 0 ) ) != MAP_FAILED ) 03868 { 03869 MD5_Update( &state, (unsigned char *) m, size ); 03870 MD5_Final( digest, &state ); 03871 munmap( m, size ); 03872 03873 for ( di = 0, rc = 0; di < 16; ++di, rc += 2 ) 03874 { 03875 temp[ rc ] = hex[ digest[di] >> 4 ]; 03876 temp[ rc + 1 ] = hex[ digest[di] & 15 ]; 03877 } 03878 temp[ 32 ] = 0; 03879 sprintf( temp, "%s", temp ); 03880 03881 if( buf == NULL ) 03882 buf = strdup( temp ); 03883 else 03884 strcpy( buf, temp ); 03885 } 03886 else 03887 { 03888 if( buf ) 03889 strcpy( buf, "0" ); 03890 else 03891 buf = strdup( "0" ); 03892 return buf; 03893 } 03894 close( fd ); 03895 return buf; 03896 }
void RioMd5::copyCache | ( | RioMd5 * | srcMd5 | ) |
copyCache makes md5Cache equal as srcMd5.md5Cache, if this instance of RioMd5 was created with cache; used to load cache from another cache
Definition at line 3721 of file RioExplorer.cpp.
03722 { 03723 if( !srcDirectory.isNull() ) //cache created 03724 { 03725 md5Cache.clear(); 03726 03727 vector<QDomElement>::iterator it; 03728 for( it = srcMd5->md5Cache.begin(); it != srcMd5->md5Cache.end(); it++ ) 03729 { 03730 QDomElement newElement = it->cloneNode().toElement(); 03731 md5Cache.push_back( newElement ); 03732 } 03733 } 03734 }
bool RioMd5::getMd5Sum | ( | char * | objectName, | |
char * | md5sum, | |||
bool | notifyError = false | |||
) |
getMd5sum obtém o md5 checksum do arquivo objectName e armazena em md5sum; armazena NULL caso objectName seja um diretório ou a operação falhe; retorna true se a operação for realizada com sucesso, e false caso contrário.
O checksum é obtido, para arquivos locais, através de cálculo ou, se possível, busca na cache (que já está carregada), e para arquivos remotos, solicitando ao servidor. O parâmetro booleano notifyError (default true) indica se getObjectMd5Sum deve ou não imprimir erro caso objectName não exista. Se a cache for utilizada, ela é atualizada conforme seja necessário.
Definition at line 3463 of file RioExplorer.cpp.
03464 { 03465 bool found = false; 03466 03467 QString name( objectName ); 03468 // MD5Sum cannot be calculated if the cache is used, but the searched file 03469 // is outside the scope of the source directory of the cache 03470 if( !srcDirectory.isNull() && 03471 name.left( srcDirectory.length() ) != srcDirectory ) 03472 { 03473 md5sum = NULL; 03474 return false; 03475 } 03476 03477 if( !parent->checkSession( md5Session ) ) 03478 { 03479 md5sum = NULL; 03480 return false; 03481 } 03482 ObjectInfo searchInfo; 03483 if (!parent->getObjectInfo( (char *)objectName, md5Session, &searchInfo, 03484 notifyError )) 03485 { 03486 md5sum = NULL; 03487 return false; 03488 } 03489 03490 #ifdef RIO_DEBUG2 03491 RioErr << "getMd5Sum for " << objectName << endl; 03492 #endif 03493 03494 if( md5Session == NULL ) //LOCAL object 03495 { 03496 if( !srcDirectory.isEmpty() ) //cache is used 03497 { 03498 //consistency check information: size and modification time 03499 RioObjectSize size = searchInfo.getSize(); 03500 AccessTime date = searchInfo.getTime(); 03501 03502 QString stringSize; 03503 stringSize += QString::number( size ); 03504 03505 //in the following lines, the method QString::rightJustify is used 03506 //to ensure formatting of date with the right amount of digits for 03507 //each parameter 03508 QString stringDate; 03509 stringDate += QString::number( date.Year ).rightJustify( 4, '0' ); 03510 stringDate += QString::number( date.Month ).rightJustify( 2, '0' ); 03511 stringDate += QString::number( date.Day ).rightJustify( 2, '0' ); 03512 stringDate += QString::number( date.Hour ).rightJustify( 2, '0' ); 03513 stringDate += QString::number( date.Minute ).rightJustify( 2, '0' ); 03514 03515 //relative path (to the main cache directory) of the file 03516 QString searchName = QString( objectName ); 03517 searchName.remove( 0, srcDirectory.length() ); 03518 searchName.remove( 0, 1 ); 03519 03520 vector<QDomElement>::iterator it; 03521 for( it = md5Cache.begin(); it != md5Cache.end() && !found; it++ ) 03522 { 03523 if( (*it).attribute( "name" ) == searchName ) 03524 //found file on the cache 03525 { 03526 if( searchInfo.isDir() ) 03527 //don't check consistency for directories 03528 { 03529 md5sum = NULL; 03530 return true; 03531 } 03532 03533 found = true; 03534 03535 //CASE 1: consistency OK 03536 if( stringSize == (*it).attribute( "size" ) && 03537 stringDate == (*it).attribute( "date" ) ) 03538 { 03539 #ifdef RIO_DEBUG2 03540 RioErr << "CASE 1: cache updated" << endl; 03541 #endif 03542 03543 strcpy( md5sum, 03544 (char *)(*it).attribute( "md5sum" ).latin1() ); 03545 //Why explicit typecast? 03546 } 03547 //CASE 2: consistency not OK: update cache 03548 else 03549 { 03550 #ifdef RIO_DEBUG2 03551 RioErr << "CASE 2: cache outdated" << endl; 03552 RioErr << " file size = " << stringSize.latin1() 03553 << ", file date = " << stringDate.latin1() << endl; 03554 RioErr << "cache size = " << (*it).attribute( "size" ).latin1() 03555 << ", cache date = " << (*it).attribute( "date" ).latin1() << endl; 03556 #endif 03557 03558 (*it).setAttribute( "size", stringSize ); 03559 (*it).setAttribute( "date", stringDate ); 03560 03561 char buffer[MD5SIZE]; 03562 parent->setMD5Calculation( objectName, false ); 03563 QString md5 = calculateMD5( objectName, buffer ); 03564 parent->setMD5Calculation( objectName, true ); 03565 (*it).setAttribute( "md5sum", md5 ); 03566 strcpy( md5sum, (char *)md5.latin1() ); 03567 } 03568 return true; 03569 } 03570 } 03571 //CASE 3: file not found on the cache: add it 03572 if( !found ) 03573 { 03574 #ifdef RIO_DEBUG2 03575 RioErr << "CASE 3: no entry on cache" << endl; 03576 #endif 03577 03578 char buffer[MD5SIZE]; 03579 parent->setMD5Calculation( objectName, false ); 03580 QString md5 = calculateMD5( objectName, buffer ); 03581 parent->setMD5Calculation( objectName, true ); 03582 03583 if( searchInfo.isDir() ) //md5sum of a directory is NULL 03584 { 03585 md5sum = NULL; 03586 QDomDocument doc( "document" ); 03587 QDomElement newElement = doc.createElement( "dir" ); 03588 newElement.setAttribute( "name", searchName ); 03589 md5Cache.push_back( newElement ); 03590 03591 return true; 03592 } 03593 03594 QDomDocument doc( "document" ); 03595 QDomElement newElement = doc.createElement( "file" ); 03596 newElement.setAttribute( "name", searchName ); 03597 newElement.setAttribute( "md5sum", md5 ); 03598 newElement.setAttribute( "size", stringSize ); 03599 newElement.setAttribute( "date", stringDate ); 03600 md5Cache.push_back( newElement ); 03601 03602 strcpy( md5sum, (char *)md5.latin1() ); 03603 return true; 03604 } 03605 } 03606 // CASE 4: cache not used 03607 else 03608 { 03609 #ifdef RIO_DEBUG2 03610 RioErr << "CASE 4: cache not used" << endl; 03611 #endif 03612 03613 if( searchInfo.isDir() ) //md5sum of a directory is NULL 03614 { 03615 md5sum = NULL; 03616 return true; 03617 } 03618 char buffer[MD5SIZE]; 03619 parent->setMD5Calculation( objectName, false ); 03620 QString md5 = calculateMD5( objectName, buffer ); 03621 parent->setMD5Calculation( objectName, true ); 03622 strcpy( md5sum, (char *)md5.latin1() ); 03623 return true; 03624 } 03625 } 03626 // CASE 5: REMOTE or SERVER object 03627 else 03628 { 03629 #ifdef RIO_DEBUG2 03630 RioErr << "CASE 5: not a local file" << endl; 03631 #endif 03632 03633 searchInfo.getMd5sum( md5sum ); 03634 return true; 03635 } 03636 //any existing file must fit any of the five cases; otherwise, it's an error 03637 md5sum = NULL; 03638 return false; 03639 }
bool RioMd5::importData | ( | QString | srcDirectory, | |
CRioSession * | srcSession | |||
) |
importData gets data from all files in srcDirectory and stores on md5Cache if RioMd5 was created with cache; used to load cache from remote md5 data
Definition at line 3740 of file RioExplorer.cpp.
03741 { 03742 #ifdef RIO_DEBUG2 03743 RioErr << "Importing MD5 data from the RIO Session" << endl; 03744 #endif 03745 03746 if( !srcDirectory.isNull() ) //cache created 03747 { 03748 md5Cache.clear(); 03749 03750 ObjectInfo dirInfo; 03751 vector<ObjectInfo> objInfo; 03752 vector<ObjectInfo> localObjInfo; 03753 vector<ObjectInfo>::iterator objIterator; 03754 vector<ObjectInfo>::iterator localObjIterator; 03755 03756 if( !parent->getObjectInfo( (char*)srcDirectory.latin1(), srcSession, 03757 &dirInfo, false ) ) 03758 return false; 03759 03760 if( !parent->ls( &dirInfo, &objInfo, srcSession, true, true ) ) 03761 return false; 03762 03763 if( !parent->getObjectInfo( this->srcDirectory.latin1(), md5Session, 03764 &dirInfo, false ) ) 03765 return false; 03766 03767 if( !parent->ls( &dirInfo, &localObjInfo, md5Session, true, true ) ) 03768 return false; 03769 03770 for( objIterator = objInfo.begin(); 03771 objIterator != objInfo.end(); 03772 objIterator++ ) 03773 { 03774 char md5[MD5SIZE]; 03775 QString relativePath; 03776 QString stringSize; 03777 QString stringDate; 03778 AccessTime date; 03779 RioObjectSize size; 03780 03781 if( objIterator->isDir() ) 03782 { 03783 relativePath = objIterator->getFullName(); 03784 03785 QDomDocument doc( "document" ); 03786 QDomElement newElement = doc.createElement( "dir" ); 03787 newElement.setAttribute( "name", relativePath ); 03788 md5Cache.push_back( newElement ); 03789 } 03790 else 03791 { 03792 relativePath = objIterator->getFullName(); 03793 03794 size = objIterator->getSize(); 03795 stringSize += QString::number( size ); 03796 03797 objIterator->getMd5sum( md5 ); 03798 // Unlike the "name", "md5sum" and "size" properties, the "date" 03799 // property does not need to be equal for both files in order 03800 // for them to match. We must use the local file as source of 03801 // this property's value, or we run the risk of causing an 03802 // inconsistency when checking whether the MD5Sum needs to be 03803 // recalculated. 03804 for( localObjIterator = localObjInfo.begin(); 03805 localObjIterator != localObjInfo.end(); 03806 localObjIterator++ ) 03807 if( localObjIterator->getFullName() == objIterator->getFullName() ) 03808 break; 03809 03810 date = localObjIterator->getTime(); 03811 03812 // In the following lines, the method QString::rightJustify is 03813 // used to ensure formatting of date with the right amount of 03814 // digits for each parameter. 03815 stringDate += QString::number( date.Year ).rightJustify( 4, '0' ); 03816 stringDate += QString::number( date.Month ).rightJustify( 2, '0' ); 03817 stringDate += QString::number( date.Day ).rightJustify( 2, '0' ); 03818 stringDate += QString::number( date.Hour ).rightJustify( 2, '0' ); 03819 stringDate += QString::number( date.Minute ).rightJustify( 2, '0' ); 03820 03821 QDomDocument doc( "document" ); 03822 QDomElement newElement = doc.createElement( "file" ); 03823 newElement.setAttribute( "name", relativePath ); 03824 newElement.setAttribute( "md5sum", md5 ); 03825 newElement.setAttribute( "size", stringSize ); 03826 newElement.setAttribute( "date", stringDate ); 03827 md5Cache.push_back( newElement ); 03828 } 03829 } 03830 } 03831 return true; 03832 }
void RioMd5::loadCache | ( | QString | src, | |
vector< QDomElement > & | md5Cache | |||
) | [private] |
loadCache carrega todos os itens armazenados na cache do diretório src e de todos os seus subdiretórios no vetor md5Cache.
Definition at line 3397 of file RioExplorer.cpp.
03398 { 03399 //loading main XML structure 03400 QString cacheFile = src + '/' + MD5CACHEFILE; 03401 QDomDocument doc( cacheFile ); 03402 QFile file( cacheFile ); 03403 #ifdef RIO_DEBUG2 03404 RioErr << "Loading cache: " << cacheFile.latin1() << endl; 03405 #endif 03406 if ( !file.open( IO_ReadWrite ) ) 03407 { 03408 #ifdef RIO_DEBUG2 03409 RioErr << "Could not open/create MD5Sum cache file." << endl; 03410 #endif 03411 return; 03412 } 03413 if ( !doc.setContent( &file ) ) 03414 { 03415 #ifdef RIO_DEBUG2 03416 RioErr << "Could not set content: probably a corrupted or empty MD5Sum " 03417 << "cache file." 03418 << endl; 03419 #endif 03420 file.close(); 03421 return; 03422 } 03423 03424 //for each element: 03425 //1) add it to the cache vector 03426 //2) if it's a directory, load its cache too 03427 QDomNode node = doc.documentElement().firstChild(); 03428 while( !node.isNull() ) 03429 { 03430 if( node.isElement() ) 03431 { 03432 QDomElement elem = node.toElement(); 03433 QString path = src.copy(); 03434 03435 //getting relative path (to the main cache directory) of the file 03436 path.remove( 0, srcDirectory.length() ); 03437 path.remove( 0, 1 ); 03438 if( !path.isEmpty() ) path += '/'; 03439 path += elem.attribute( "name" ); 03440 elem.setAttribute( "name", path ); 03441 03442 md5Cache.push_back( elem ); 03443 if( ( elem.tagName() == "dir" ) ) 03444 loadCache( src + "/" + 03445 elem.attribute( "name" ).section( '/', -1 ), 03446 md5Cache ); 03447 } 03448 node = node.nextSibling(); 03449 } 03450 file.close(); 03451 }
bool RioMd5::updateCache | ( | ) |
This method ensures that the cache, if existant, is fully updated.
That is, a file is present in the cache if, an only if, it exists in srcDirectory.
Definition at line 3645 of file RioExplorer.cpp.
03646 { 03647 #ifdef RIO_DEBUG1 03648 RioErr << "Entered updateCache" << endl; 03649 #endif 03650 03651 if( !parent->checkSession( md5Session ) ) 03652 return false; 03653 03654 #ifdef RIO_DEBUG2 03655 if( !srcDirectory.isEmpty() ) 03656 RioErr << "Updating cache for " << srcDirectory.latin1() << endl; 03657 #endif 03658 03659 if( !srcDirectory.isEmpty() ) //cache is used 03660 { 03661 ObjectInfo objInfo; 03662 vector<ObjectInfo> objectsInfo; 03663 vector<ObjectInfo>::iterator lsIterator; 03664 vector<QDomElement>::iterator cacheIterator; 03665 char md5Buffer[MD5SIZE]; 03666 memset( md5Buffer, 0, sizeof( md5Buffer ) ); 03667 03668 if( !parent->getObjectInfo( (char*)srcDirectory.latin1(), md5Session, 03669 &objInfo ) || 03670 !parent->ls( &objInfo, &objectsInfo, md5Session, true, true ) 03671 ) 03672 { 03673 #ifdef RIO_DEBUG1 03674 RioErr << "Leaving updateCache [1]" << endl; 03675 #endif 03676 return false; 03677 } 03678 03679 //this loop gets the MD5 checksum for all files in srcDirectory. This 03680 //will ensure the cache contains all existent files 03681 for( lsIterator = objectsInfo.begin(); lsIterator != objectsInfo.end(); 03682 lsIterator++ ) 03683 { 03684 if( (char *)MD5CACHEFILE.latin1() != lsIterator->getName() ) 03685 { 03686 QString fileName = srcDirectory + '/' + 03687 lsIterator->getFullName(); 03688 getMd5Sum( (char *)fileName.latin1(), md5Buffer ); 03689 } 03690 } 03691 //this loop removes from the cache all files that no inter exist 03692 for( cacheIterator = md5Cache.begin(); 03693 cacheIterator != md5Cache.end(); ) 03694 { 03695 QString fileName = srcDirectory + '/' + 03696 cacheIterator->attribute( "name" ); 03697 if( !parent->getObjectInfo( (char *)fileName.latin1(), md5Session, 03698 &objInfo ) ) 03699 md5Cache.erase( cacheIterator ); 03700 else 03701 cacheIterator++; 03702 } 03703 #ifdef RIO_DEBUG1 03704 RioErr << "Leaving updateCache [2]" << endl; 03705 #endif 03706 return true; 03707 } 03708 else //cache isn't used: no need to update 03709 { 03710 #ifdef RIO_DEBUG1 03711 RioErr << "Leaving updateCache [3]" << endl; 03712 #endif 03713 return true; 03714 } 03715 }
vector<QDomElement> RioMd5::md5Cache [private] |
Definition at line 244 of file RioExplorer.h.
QString RioMd5::MD5CACHEFILE [private] |
Definition at line 245 of file RioExplorer.h.
CRioSession* RioMd5::md5Session [private] |
Definition at line 242 of file RioExplorer.h.
RioExplorer* RioMd5::parent [private] |
Definition at line 241 of file RioExplorer.h.
QString RioMd5::srcDirectory [private] |
Definition at line 243 of file RioExplorer.h.