#include <fsc_RawScan.h>

Definition at line 29 of file fsc_RawScan.h.
Public Member Functions | |
| fsc_RawScan (bool a_pmThread, fsc_RawCollector &a_collector, char a_clientPathSeparator=PATH_SEPARATOR) | |
| ~fsc_RawScan (void) | |
| void | ScanAllFileID () |
| ScanAllFileID() method sequentialy reads fileID from 1 forward. | |
| void | DirTreeWalk (ivd_RecordIDX_t a_fileID, cmn_Path a_path) |
| DirTreeWalk() method start from root reads all members and continue for each directory. | |
Public Attributes | |
| log_CLASSID_m | |
Private Member Functions | |
| void | ScanAllGeneration (fsc_DataL_t &a_dataL) |
| void | ScanAllCopy (ivd_RecordIDX_t a_idx, UInt32_t a_size) |
| void | ScanAllSplit (ivd_RecordIDX_t a_idx, UInt32_t a_size) |
Private Attributes | |
| const bool | m_pmThread |
| set if scan is run in PM thread | |
| fsc_RawCollector & | m_collector |
| const char | m_clientPathSeparator |
Friends | |
| class | ut_fsc_RawScan |
| fsc_RawScan::fsc_RawScan | ( | bool | a_pmThread, | |
| fsc_RawCollector & | a_collector, | |||
| char | a_clientPathSeparator = PATH_SEPARATOR | |||
| ) |
Definition at line 48 of file fsc_RawScan.cpp.
References log_FUNC_m.
00051 : 00052 m_pmThread(a_pmThread), 00053 m_collector(a_collector), 00054 m_clientPathSeparator(a_clientPathSeparator) 00055 { 00056 log_FUNC_m(fsc_RawScan); 00057 } //============================================================================//
| fsc_RawScan::~fsc_RawScan | ( | void | ) | [inline] |
| void fsc_RawScan::ScanAllFileID | ( | ) |
ScanAllFileID() method sequentialy reads fileID from 1 forward.
Definition at line 60 of file fsc_RawScan.cpp.
References cmn_HexDump(), dbg_DETAIL, dbg_NORM, g_dataLRF_p, g_fscUpdate_x, fsc_DataL_t::generationIdx, log_DBG_m, log_FUNC_m, m_collector, m_pmThread, fsc_RawCollector::ProcFileID(), fsc_RawCollector::ProcRecDataL(), fio_RelFile::ReadRec(), and ScanAllGeneration().
Referenced by i_FSC_i::CollectByVolume(), i_FSC_i::DeleteEntries(), main(), i_FSC_i::RedundantCopy(), and i_FSC_i::ReorgScan().
00060 { 00061 log_FUNC_m(ScanAllFileID); 00062 const int dataLBuffSize = 1024; 00063 // remove old files and dirs 00064 log_DBG_m(dbg_NORM, " Fast read of dataL. buff size " << 00065 dataLBuffSize << " of records.\n"); 00066 00067 // fsc_RawMedVolPathCollector m_collector(string("cosmos"), 3, 1); 00068 00069 fsc_DataL_t dataL[dataLBuffSize]; 00070 log_DBG_m(dbg_DETAIL, "allocated dataL:" << &dataL << 00071 " last element address: " << &dataL[dataLBuffSize-1]); 00072 ivd_RecordIDX_t fileID = 1; 00073 if (m_pmThread) { 00074 while (fileID < g_dataLRF_p->FirstNewIDX()) { 00075 // lock to preven changes, but unlock every now and then 00076 // to prevet FSC update starvation 00077 cmn_MutexLock l(g_fscUpdate_x); 00078 log_DBG_m(dbg_DETAIL, "fileID: "); /*<< fileID << 00079 " allocated dataL:" << &dataL);*/ 00080 00081 int read = g_dataLRF_p->ReadRec(fileID, &dataL, dataLBuffSize); 00082 00083 log_DBG_m(dbg_DETAIL, "Read " << read << " records." << endl); 00084 register fsc_DataL_t *ip = dataL; 00085 register fsc_DataL_t *ep = &dataL[read]; 00086 for (; ip < ep; ++ip, ++fileID ) { 00087 if (ip->generationIdx > 0) { 00088 log_DBG_m(dbg_DETAIL, "Got DataL from = " << fileID << endl << 00089 cmn_HexDump(ip, sizeof(fsc_DataL_t), sizeof(fsc_DataL_t), false) ); 00090 m_collector.ProcFileID(fileID); 00091 fsc_nsElement_t nsElement(fileID); 00092 m_collector.ProcRecDataL(nsElement); 00093 ScanAllGeneration(*ip); 00094 } 00095 } 00096 } 00097 } 00098 else { // no lock need 00099 while (fileID < g_dataLRF_p->FirstNewIDX()) { 00100 int read = g_dataLRF_p->ReadRec(fileID, &dataL, dataLBuffSize); 00101 log_DBG_m(dbg_DETAIL, "Read " << read << " records." << endl); 00102 register fsc_DataL_t *ip = dataL; 00103 register fsc_DataL_t *ep = &dataL[read]; 00104 for (; ip < ep; ++ip, ++fileID ) { 00105 if (ip->generationIdx > 0) { 00106 log_DBG_m(dbg_DETAIL, "Got DataL from = " << fileID << endl << 00107 cmn_HexDump(ip, sizeof(fsc_DataL_t), sizeof(fsc_DataL_t), false) ); 00108 m_collector.ProcFileID(fileID); 00109 fsc_nsElement_t nsElement(fileID); 00110 m_collector.ProcRecDataL(nsElement); 00111 ScanAllGeneration(*ip); 00112 } 00113 } 00114 } 00115 } 00116 }


| void fsc_RawScan::DirTreeWalk | ( | ivd_RecordIDX_t | a_fileID, | |
| cmn_Path | a_path | |||
| ) |
DirTreeWalk() method start from root reads all members and continue for each directory.
Definition at line 360 of file fsc_RawScan.cpp.
References dbg_DETAIL, fsc_nsElement::Dump(), g_fscUpdate_x, fsc_nsDirEntryFormattedVec::GetFirstMemPtr(), fsc_nsDirEntryVec::GetNextDirEntryVecPtr(), fsc_nsDirEntryFormattedVec::GetNextMemPtr(), fsc_nsElement::GetStandAttrPtr(), log_DBG_m, log_FUNC_m, log_NOTE_m, m_clientPathSeparator, m_collector, fsc_nsElement_t::memberIdx, fsc_nsElement_t::migID, fsc_nsElement_t::nameIdx, fsc_nsElement_t::nameType, df_StandardAttr_t::NetToHost(), nit_NAME, NULL, fsc_nsElement_t::numOfMember, fsc_nsElement_t::numOfName, path, and fsc_RawCollector::ProcDirElement().
Referenced by i_FSC_i::DelExpiredFiles().
00360 { 00361 log_FUNC_m(DirTreeWalk); 00362 fsc_nsElement_t nsElement(a_fileID); 00363 log_DBG_m(dbg_DETAIL, "Got nsElement of fileID " << a_fileID 00364 << " on path " << a_path); 00365 log_DBG_m(dbg_DETAIL, "nameType " << (int)nsElement.nameType 00366 << ", memIdx " << nsElement.memberIdx 00367 << ", mem in 1st vector " << (int)nsElement.numOfMember 00368 << " migID " << nsElement.migID); 00369 if ( nsElement.nameType == nit_NAME 00370 || ( (a_fileID == 0) // or root with members. NOTE root has no name 00371 && (nsElement.memberIdx))) { 00372 fsc_nsString name(nsElement.numOfName, nsElement.nameIdx); 00373 log_DBG_m(dbg_DETAIL, "name '" << name << "'"); 00374 if (nsElement.memberIdx) { // is a directory 00375 // lock FSC, not for update, but to preven chances by others 00376 fsc_nsDirEntryVec *members_p = NULL; 00377 { 00378 cmn_MutexLock l(g_fscUpdate_x); 00379 members_p = new fsc_nsDirEntryVec(nsElement.numOfMember, nsElement.memberIdx); 00380 fsc_nsDirEntryVec *p = members_p; 00381 // read all vectors to make a vector chain 00382 while (NULL != (p = p->GetNextDirEntryVecPtr())) { 00383 // empty 00384 } 00385 } 00386 if (members_p) { 00387 // cmn_Path path(a_path + name); 00388 fsc_nsDirEntryVec *p = members_p; 00389 // scan through all vectors is a little tricky 00390 // there are many fsc_nsDirEntryVec linked in a list. 00391 // Each contains directory members as fileIDs 00392 // So function getNextMemPtr return a pointer to fileID 00393 // if pointer is NULL then end of the vector is reached 00394 // at this point get next vector and if no vector exist then 00395 // all members are read 00396 while (p != NULL) { 00397 ivd_RecordIDX_t *el = p->GetFirstMemPtr(); 00398 while (el != NULL) { 00399 string path(a_path); 00400 if (path.size() > 0) { 00401 path += m_clientPathSeparator + name; 00402 } 00403 else { 00404 path = name; 00405 } 00406 DirTreeWalk(*el, path ); 00407 p->GetNextMemPtr(el); 00408 } 00409 p = p->GetNextDirEntryVecPtr(); 00410 } 00411 00412 delete members_p; 00413 } 00414 } 00415 else { 00416 fsc_nsElement Element(a_fileID); 00417 df_StandardAttr_t *attr = Element.GetStandAttrPtr(); 00418 if (attr == NULL) { 00419 ostringstream sstr; 00420 Element.Dump(sstr); 00421 log_NOTE_m("FileID " << a_fileID << " has no attributes stored." 00422 << sstr.str()); 00423 return; 00424 } 00425 attr->NetToHost(); 00426 m_collector.ProcDirElement(nsElement, *attr, a_path, name); 00427 } 00428 } 00429 }


| void fsc_RawScan::ScanAllGeneration | ( | fsc_DataL_t & | a_dataL | ) | [private] |
Definition at line 119 of file fsc_RawScan.cpp.
References assert, cmn_HexDump(), cmn_Num2Str(), dbg_DETAIL, dlc_Copy, dlc_MediaPos, dlc_Split, fsc_maxNumOfMember_c, fsc_maxRFVecSize_c, g_generationRF_p, fsc_DataL_t::generationIdx, fsc_RawCollector::GetNSNameType(), fio_RelFile::Idx2Pos(), ie_INVALID_ARG, log_DBG_m, log_FUNC_m, m_collector, mvds_DELETED, mvds_LASTGENERATION, mvds_NONSC, nit_DELETED, nit_NAME, nit_NSCMISSING, fsc_DataL_t::numOfAllGen, fsc_DataL_t::numOfElement, fio_File::PosRead(), fsc_RawCollector::PostCopiesProc(), fsc_RawCollector::ProcRecGeneration(), fsc_RawCollector::ProcRecMedPosMgr(), fsc_RawCollector::ProcVecGeneration(), ScanAllCopy(), and ScanAllSplit().
Referenced by ScanAllFileID().
00119 { 00120 log_FUNC_m(ScanAllGeneration); 00121 // 00122 Int32_t numOfGen = a_dataL.numOfAllGen; 00123 UInt32_t numOfGenInVec = a_dataL.numOfElement; 00124 ivd_FileRetSize_t read_result; 00125 00126 if (numOfGen == 0 && numOfGenInVec == 0){ 00127 // not a single element -- should not happen at all 00128 log_DBG_m(dbg_DETAIL, "Generation does not have a single element: Ignored"); 00129 return; 00130 } 00131 00132 if (numOfGen == 0){ 00133 // backward compatybility see bug 3990 00134 numOfGen = a_dataL.numOfElement; 00135 } 00136 00137 if (numOfGenInVec == 0){ 00138 // we are at a vector boundary so fsc_maxRFVecSize_c (256) elements are 00139 // in the vector 00140 numOfGenInVec = fsc_maxRFVecSize_c ; // last ( fsc_maxRFVecSize_c ths ) 00141 // element contains the link 00142 } 00143 00144 vector<fsc_Generation_t> generation(numOfGen); 00145 log_DBG_m(dbg_DETAIL, "Vector generation allocated: " << generation.size()); 00146 00147 register fsc_Generation_t *ip = &generation[0]; 00148 00149 ivd_FilePosition_t pos = g_generationRF_p->Idx2Pos(a_dataL.generationIdx); 00150 log_DBG_m(dbg_DETAIL, "Seeking to position: " << pos << 00151 " reading a_dataL.numOfElement * sizeof(fsc_Generation_t):" << 00152 numOfGenInVec * sizeof(fsc_Generation_t) << " byte = " << 00153 numOfGenInVec << " records of " << 00154 sizeof(fsc_Generation_t) << " byte" ); 00155 00156 // read first vector 00157 read_result = g_generationRF_p->PosRead(pos, 00158 ip, 00159 numOfGenInVec * sizeof(fsc_Generation_t)); 00160 00161 // UNCOMMENT BELOW IF YOU LIKE TO DEBUG 00162 //log_DBG_m(dbg_DETAIL, "P1: read " << read_result << " byte " << 00163 // (Int32_t) numOfGenInVec << " Records have been read Dump: " << endl << 00164 // cmn_HexDump(ip, numOfGenInVec * sizeof(fsc_Generation_t), 00165 // sizeof(fsc_Generation_t), false ) ); 00166 00167 if (numOfGen >= fsc_maxRFVecSize_c) { // follow chain of generation's vector 00168 numOfGenInVec -= 1; // Last entry contains the link to the next vector so read one less 00169 numOfGen -= numOfGenInVec; 00170 ip += numOfGenInVec; 00171 log_DBG_m(dbg_DETAIL, " numOfGen:" << (Int32_t) numOfGen << " fsc_maxRFVecSize_c:" << fsc_maxRFVecSize_c ); 00172 while (numOfGen > fsc_maxRFVecSize_c) { 00173 // NOTE: the structure is named fio_UnusedRec_t, in fact thie points to the next USED vector. 00174 pos = g_generationRF_p->Idx2Pos(reinterpret_cast<fio_UnusedRec_t*>(ip)->next); 00175 log_DBG_m(dbg_DETAIL, "Seeking to position: " << pos << 00176 " reading a_dataL.numOfElement * sizeof(fsc_Generation_t):" << 00177 fsc_maxRFVecSize_c * sizeof(fsc_Generation_t) << " byte = " << 00178 fsc_maxRFVecSize_c << " records of " << 00179 sizeof(fsc_Generation_t) << " byte" ); 00180 00181 // read all vectors except last 00182 // 256 elements, last elem contain link to next vector 00183 read_result = g_generationRF_p->PosRead(pos, 00184 ip, 00185 fsc_maxRFVecSize_c * sizeof(fsc_Generation_t)); 00186 // UNCOMMENT BELOW IF YOU LIKE TO DEBUG 00187 //log_DBG_m(dbg_DETAIL, "P2: read " << read_result << 00188 // "byte" << (Int32_t) fsc_maxRFVecSize_c << 00189 // " Records have been read Dump: " << endl << 00190 // cmn_HexDump(ip, fsc_maxRFVecSize_c * sizeof(fsc_Generation_t), 00191 // sizeof(fsc_Generation_t), false ) ); 00192 numOfGen -= fsc_maxNumOfMember_c; 00193 ip += fsc_maxNumOfMember_c; 00194 log_DBG_m(dbg_DETAIL, " numOfGen:" << (Int32_t) numOfGen << " fsc_maxRFVecSize_c:" << fsc_maxRFVecSize_c ); 00195 } 00196 pos = g_generationRF_p->Idx2Pos(reinterpret_cast<fio_UnusedRec_t*>(ip)->next); 00197 log_DBG_m(dbg_DETAIL, "Seeking to position: " << pos << 00198 " reading a_dataL.numOfElement * sizeof(fsc_Generation_t):" << 00199 numOfGen * sizeof(fsc_Generation_t) << " byte = " << 00200 numOfGen << " records of " << 00201 sizeof(fsc_Generation_t) << " byte" ); 00202 // read last vector without last element 00203 read_result = g_generationRF_p->PosRead(pos, 00204 ip, 00205 numOfGen * sizeof(fsc_Generation_t)); 00206 00207 // UNCOMMENT BELOW IF YOU LIKE TO DEBUG 00208 //log_DBG_m(dbg_DETAIL, "P3: read" << read_result << " byte " << 00209 // numOfGen << " Records have been read Dump: " << endl << 00210 // cmn_HexDump(ip, numOfGen * sizeof(fsc_Generation_t), 00211 // sizeof(fsc_Generation_t), false ) ); 00212 00213 // the assert happens if we do not read fsc_maxNumOfMember_c (255) members 00214 // the last vector allways has one less records than the maximum, because 00215 // it doen not contain a pointer to the next record. 00216 assert(numOfGen == fsc_maxNumOfMember_c); 00217 } 00218 00219 log_DBG_m(dbg_DETAIL, "R Generations from = " << a_dataL.generationIdx 00220 << " size = " << a_dataL.numOfAllGen << endl << 00221 cmn_HexDump(&generation[0], 00222 a_dataL.numOfAllGen * sizeof(fsc_Generation_t), 00223 sizeof(fsc_Generation_t), 00224 false) 00225 ); 00226 00227 // for each generation 00228 m_collector.ProcVecGeneration(generation); 00229 00230 00231 ip = &generation[0]; 00232 register fsc_Generation_t *ep = &generation[a_dataL.numOfAllGen]; 00233 int genCount = 1; 00234 for (;ip < ep; ++ip ) { 00235 if (genCount == 1) { 00236 if (m_collector.GetNSNameType() == nit_NAME) { 00237 m_collector.ProcRecGeneration(*ip, mvds_LASTGENERATION); 00238 } 00239 else if (m_collector.GetNSNameType() == nit_NSCMISSING) { 00240 m_collector.ProcRecGeneration(*ip, mvds_NONSC); 00241 } 00242 else { 00243 m_collector.ProcRecGeneration(*ip, 0); 00244 } 00245 } 00246 else if ( genCount == 2 00247 && m_collector.GetNSNameType() == nit_DELETED) { 00248 m_collector.ProcRecGeneration(*ip, mvds_DELETED | mvds_LASTGENERATION); 00249 } 00250 else { 00251 m_collector.ProcRecGeneration(*ip, 0); 00252 } 00253 genCount++; 00254 00255 switch (ip->nextEntity.dlcType) { 00256 case dlc_MediaPos : { 00257 m_collector.ProcRecMedPosMgr(ip->nextEntity.GetMedPos()); 00258 break; 00259 } 00260 case dlc_Copy : { 00261 ScanAllCopy(ip->nextEntity.vector.entryIdx, 00262 ip->nextEntity.vector.numOfElement); 00263 break; 00264 } 00265 case dlc_Split : { 00266 ScanAllSplit(ip->nextEntity.vector.entryIdx, 00267 ip->nextEntity.vector.numOfElement); 00268 break; 00269 } 00270 default : { 00271 log_FUNC_m(ScanAllGeneration); 00272 throw ivd_InternalError(ie_INVALID_ARG, 00273 "Wrong dlcType =" + cmn_Num2Str((int)ip->nextEntity.dlcType), true); 00274 break; 00275 } 00276 } 00277 m_collector.PostCopiesProc(); 00278 } 00279 }


| void fsc_RawScan::ScanAllCopy | ( | ivd_RecordIDX_t | a_idx, | |
| UInt32_t | a_size | |||
| ) | [private] |
Definition at line 282 of file fsc_RawScan.cpp.
References alloca(), cmn_Num2Str(), dlc_MediaPos, dlc_NotUsed, dlc_Split, fsc_NextEntity_t::dlcType, fsc_Vector_t::entryIdx, g_copyRF_p, fsc_NextEntity_t::GetMedPos(), fio_RelFile::Idx2Pos(), ie_INVALID_ARG, log_FUNC_m, m_collector, fsc_Copy_t::nextEntity, fsc_Vector_t::numOfElement, fio_File::PosRead(), fsc_RawCollector::PostRecCopy(), fsc_RawCollector::ProcRecCopy(), fsc_RawCollector::ProcRecMedPosMgr(), ScanAllSplit(), and fsc_NextEntity_t::vector.
Referenced by ScanAllGeneration().
00282 { 00283 log_FUNC_m(ScanAllCopy); 00284 // fsc_Copy_t copy[256]; // allocate only a_size to prevent constructor call 00285 fsc_Copy_t *copy = reinterpret_cast<fsc_Copy_t*> 00286 (alloca(a_size * sizeof(fsc_Copy_t))); 00287 00288 // direct call can be use if this is a single process 00289 //static_cast<cmn_File*>(g_copyRF_p)-> 00290 g_copyRF_p->PosRead(g_copyRF_p->Idx2Pos(a_idx), 00291 copy, 00292 a_size * sizeof(fsc_Copy_t)); 00293 // g_copyRF_p->ReadRec(a_idx, copy, a_size); 00294 // log_DBG_m(dbg_DETAIL, "R copies from = " << a_idx + (ip - copy) << endl << 00295 // cmn_HexDump(copy, a_size * sizeof(fsc_Copy_t), sizeof(fsc_Copy_t), false) ); 00296 00297 // for each generation 00298 00299 register fsc_Copy_t *ip = copy; 00300 register fsc_Copy_t *ep = ©[a_size]; 00301 for (; ip < ep; ++ip ) { 00302 m_collector.ProcRecCopy(*ip); 00303 switch (ip->nextEntity.dlcType) { 00304 case dlc_NotUsed : continue; 00305 case dlc_MediaPos : { 00306 m_collector.ProcRecMedPosMgr(ip->nextEntity.GetMedPos()); 00307 break; 00308 } 00309 case dlc_Split : { 00310 ScanAllSplit(ip->nextEntity.vector.entryIdx, 00311 ip->nextEntity.vector.numOfElement); 00312 break; 00313 } 00314 default : { 00315 log_FUNC_m(ScanAllCopy); 00316 throw ivd_InternalError(ie_INVALID_ARG, 00317 "Wrong dlcType =" + cmn_Num2Str((int)ip->nextEntity.dlcType), true); 00318 break; 00319 } 00320 } 00321 m_collector.PostRecCopy(*ip); 00322 } 00323 }


| void fsc_RawScan::ScanAllSplit | ( | ivd_RecordIDX_t | a_idx, | |
| UInt32_t | a_size | |||
| ) | [private] |
Definition at line 326 of file fsc_RawScan.cpp.
References alloca(), cmn_Num2Str(), dlc_MediaPos, fsc_NextEntity_t::dlcType, g_splitRF_p, fsc_NextEntity_t::GetMedPos(), fio_RelFile::Idx2Pos(), ie_INVALID_ARG, log_FUNC_m, m_collector, fsc_Split_t::nextEntity, fio_File::PosRead(), fsc_RawCollector::ProcRecMedPosMgr(), and fsc_RawCollector::ProcRecSplit().
Referenced by ScanAllCopy(), and ScanAllGeneration().
00326 { 00327 log_FUNC_m(ScanAllSplit); 00328 // fsc_Split_t split[256]; // allocate only a_size to prevent constructor call 00329 fsc_Split_t *split = reinterpret_cast<fsc_Split_t*> 00330 (alloca(a_size * sizeof(fsc_Split_t))); 00331 g_splitRF_p->PosRead(g_splitRF_p->Idx2Pos(a_idx), 00332 split, 00333 a_size * sizeof(fsc_Split_t)); 00334 // g_splitRF_p->ReadRec(a_idx, split, a_size); 00335 // log_DBG_m(dbg_DETAIL, "R Splits from = " << a_idx << endl << 00336 // cmn_HexDump(split, a_size * sizeof(fsc_Split_t), sizeof(fsc_Split_t), false) ); 00337 00338 // for each generation 00339 register fsc_Split_t *ip = split; 00340 register fsc_Split_t *ep = &split[a_size]; 00341 for (; ip < ep; ++ip ) { 00342 m_collector.ProcRecSplit(*ip); 00343 00344 switch (ip->nextEntity.dlcType) { 00345 case dlc_MediaPos : { 00346 m_collector.ProcRecMedPosMgr(ip->nextEntity.GetMedPos()); 00347 break; 00348 } 00349 default : { 00350 log_FUNC_m(ScanAllSplit); 00351 throw ivd_InternalError(ie_INVALID_ARG, 00352 "Wrong dlcType =" + cmn_Num2Str((int)ip->nextEntity.dlcType), true); 00353 break; 00354 } 00355 } 00356 } 00357 }


friend class ut_fsc_RawScan [friend] |
Definition at line 30 of file fsc_RawScan.h.
Definition at line 42 of file fsc_RawScan.h.
const bool fsc_RawScan::m_pmThread [private] |
set if scan is run in PM thread
Definition at line 49 of file fsc_RawScan.h.
Referenced by ScanAllFileID().
fsc_RawCollector& fsc_RawScan::m_collector [private] |
Definition at line 50 of file fsc_RawScan.h.
Referenced by DirTreeWalk(), ScanAllCopy(), ScanAllFileID(), ScanAllGeneration(), and ScanAllSplit().
const char fsc_RawScan::m_clientPathSeparator [private] |
1.5.6