Esempio n. 1
0
TZipIn::TZipIn(const TStr& FNm) : TSBase(FNm.CStr()), TSIn(FNm), ZipStdoutRd(NULL), ZipStdoutWr(NULL),
  FLen(0), CurFPos(0), Bf(NULL), BfC(0), BfL(0) {
  EAssertR(! FNm.Empty(), "Empty file-name.");
  EAssertR(TFile::Exists(FNm), TStr::Fmt("File %s does not exist", FNm.CStr()).CStr());
  FLen = 0;
  // non-zip files not supported, need uncompressed file length information
  if (FNm.GetFExt() != ".zip") {
    printf("*** Error: file %s, compression format %s not supported\n", FNm.CStr(), FNm.GetFExt().CStr());
    EFailR(TStr::Fmt("File %s: compression format %s not supported", FNm.CStr(), FNm.GetFExt().CStr()).CStr());
  }
  FLen = TZipIn::GetFLen(FNm);
  // return for malformed files
  if (FLen == 0) { return; } // empty file
  #ifdef GLib_WIN
  // create pipes
  SECURITY_ATTRIBUTES saAttr;
  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
  saAttr.bInheritHandle = TRUE;
  saAttr.lpSecurityDescriptor = NULL;
    // Create a pipe for the child process's STDOUT.
  const int PipeBufferSz = 32*1024;
  EAssertR(CreatePipe(&ZipStdoutRd, &ZipStdoutWr, &saAttr, PipeBufferSz), "Stdout pipe creation failed");
  // Ensure the read handle to the pipe for STDOUT is not inherited.
  SetHandleInformation(ZipStdoutRd, HANDLE_FLAG_INHERIT, 0);
  #else
  // no implementation needed
  #endif
  CreateZipProcess(GetCmd(FNm), FNm);
  Bf = new char[MxBfL]; BfC = BfL=-1;
  FillBf();
}
Esempio n. 2
0
/////////////////////////////////////////////////
// Simple JSON parser
bool TJsonLoader::Next() {
  if (SIn.Empty() || SIn->Eof()) {
    TStr FNm;
    if (! SIn.Empty()) { 
      printf("  %d items in file. %d items total. [%s]\n", LineNo, ItemCnt, ExeTm.GetTmStr()); }
    if (! FFile.Next(FNm)) { return false; }
    printf("JSON parse file %d: %s\n", ++FileCnt, FNm.CStr());  LineNo=0;
    if (TZipIn::IsZipExt(FNm.GetFExt())) { SIn=TZipIn::New(FNm); }
    else { SIn=TFIn::New(FNm); }
    ExeTm.Tick();
  }
  try {
    SIn->GetNextLn(Line);
    LineNo++;  ItemCnt++;
    Item.Parse(Line.CStr());
  }
  catch (PExcept Except) {
    TStr FullMsgCStr = TStr::Fmt("%s while pasing '%s' in line %d\nBEGIN LINE\n", 
      Except->GetStr().CStr(), GetCurFNm().CStr(), GetLineNo());
    FullMsgCStr += Line;
    FullMsgCStr += "\nEND LINE\n";
    SaveToErrLog(FullMsgCStr.CStr());
    ErrNotify(FullMsgCStr.CStr());
    return Next();
  }
  return true;
}
Esempio n. 3
0
void DoLayout(const TStr& GraphInFNm, TStr OutFNm, const TGVizLayout& Layout) {
  TStr LayoutExe = GetLayoutStr(Layout), Ext = OutFNm.GetFExt(), GvPath;
  #if defined(GLib_WIN)
    GvPath = "C:\\Prog\\GraphViz\\bin\\";
  #else
    GvPath = "/usr/bin/";
    Ext = ".ps";
    OutFNm = OutFNm.GetFMid() + Ext;
  #endif
  IAssert(Ext==".ps" || Ext==".gif" || Ext==".png");
  const TStr ExeCmd = TStr::Fmt("%s -T%s %s -o %s", LayoutExe.CStr(),
    Ext.CStr()+1, GraphInFNm.CStr(), OutFNm.CStr());

  if (system(ExeCmd.CStr())==0) { return; }
  #if defined(GLib_WIN)
  if (system(TStr::Fmt(".\\%s", ExeCmd.CStr()).CStr())==0) { return; }
  #else
  if (system(TStr::Fmt("./%s", ExeCmd.CStr()).CStr())==0) { return; }
  #endif
  if (system(TStr::Fmt("%s%s", GvPath.CStr(), ExeCmd.CStr()).CStr())==0) { return; }
  fprintf(stderr, "[%s:%d] Cat not find GraphViz (%s). Set the PATH.\n", __FILE__, __LINE__, ExeCmd.CStr());
  //#if defined(GLib_WIN)
  //if (ShowPlot) system(TStr::Fmt("start %s", OutFNm.CStr()).CStr());
  //#endif
}
Esempio n. 4
0
bool TFFile::Next(TStr& FNm){
  // if need to recurse
  if (!SubFFile.Empty()){
    if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
    else {SubFFile=NULL;}
  }
  // for all required file-paths
  while (FPathN<FPathV.Len()){
    // try to find anything within FPathV[FPathN] directory
    while (true) {
      // if directory not open -> open next first
      if (!FFileDesc->FDesc) {
        if ((++FPathN)<FPathV.Len()) {
          FFileDesc->FDesc = opendir(FPathV[FPathN].CStr());
        } else break;
        if (!FFileDesc->FDesc) break;   // failed to open this one; pass control to outer loop
      }

      FFileDesc->DirEnt = readdir(FFileDesc->FDesc);

      if (FFileDesc->DirEnt) {
        // found something
        TStr FBase = FFileDesc->GetFBase();
        FNm = FPathV[FPathN]+FBase;

        struct stat Stat;
        int ErrCd = stat(FNm.CStr(), &Stat);
        Assert(ErrCd==0); // !bn: assert-with-exception [pa se drugje po tej funkciji]

        if (S_ISREG(Stat.st_mode)) {
          if ((FBase!=".")&&(FBase!="..")){
            TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
            if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
             ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
              CurFNm=FNm; CurFNmN++; return true;}
          }
        } else if (S_ISDIR(Stat.st_mode) && RecurseP) {
          if ((FBase!=".")&&(FBase!="..")){
            TStr SubFPath=FPathV[FPathN]+FBase;
            TStrV SubFPathV; SubFPathV.Add(SubFPath);
            SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
            if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
            else {SubFFile=NULL;}
          }
        }
      } else {
        // end of directory; clean up (ignore DirEnt, it's allocated within FDesc), pass control to outer loop
        FFileDesc->DirEnt = NULL;
        int ErrCd = closedir(FFileDesc->FDesc);
        FFileDesc->FDesc = NULL;
        Assert(ErrCd==0);
        break;
      }
    }
  }
  // not found
  CurFNm=""; CurFNmN=-1; return false;
}
Esempio n. 5
0
TDzsBs::TDzsBs(const TStr& FPath, const TStr& WebAlias):
  TBook("Dzs-Base", "Dzs", "Lexicon"),
  DzsBsDocV(), Bix(TBix::New()){
  TStrV FPathV; FPathV.Add(FPath);
  TStrV FExtV;
  FExtV.Add("xml"); FExtV.Add("html"); FExtV.Add("htm"); FExtV.Add("txt");
  TFFile FFile(FPathV, FExtV, true); TStr FNm; int FNmN=0;
  while (FFile.Next(FNm)){
    printf("%d\r", ++FNmN);
    PDzsBsDoc DzsBsDoc;
    if (FNm.GetFExt().GetUc()==".XML"){
      PXmlDoc XmlDoc=TXmlDoc::LoadTxt(FNm);
      DzsBsDoc=TDzsBsDoc::GetDzsBsDoc(FNm, XmlDoc, FPath, WebAlias);
    } else {
      PHtmlDoc HtmlDoc=THtmlDoc::LoadTxt(FNm, hdtAll, false);
      DzsBsDoc=TDzsBsDoc::GetDzsBsDoc(FNm, HtmlDoc, FPath, WebAlias);
    }
    AddDoc(DzsBsDoc);
  }
}
Esempio n. 6
0
//////////////////////////////////////
// File-Download-Function
void TSASFunFile::LoadFunFileV(const TStr& FPath, TSAppSrvFunV& SrvFunV) {
	TFFile File(FPath, "", false); TStr FNm;
	while (File.Next(FNm)) {
		TStr FExt = FNm.GetFExt();
		TStr FUrl = FNm.GetSubStr(FPath.Len());
		FUrl.ChangeChAll('\\', '/');
		printf("%s %s %s\n", FNm.CStr(), FExt.CStr(), FUrl.CStr());
		if (FExt == ".htm") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::TextHtmlFldVal)); }
		else if (FExt == ".html") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::TextHtmlFldVal)); }
		else if (FExt == ".js") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::TextJavaScriptFldVal)); }
		else if (FExt == ".css") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::TextCssFldVal)); }
		else if (FExt == ".jpg") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::ImageJpgFldVal)); }
		else if (FExt == ".jpeg") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::ImageJpgFldVal)); }
		else if (FExt == ".gif") { SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::ImageGifFldVal)); }
		else {
			printf("Unknown MIME type for extension '%s' for file '%s'", FExt.CStr(), FNm.CStr());
			SrvFunV.Add(TSASFunFile::New(FUrl, FNm, THttp::AppOctetFldVal)); 
		}
	}	
}
Esempio n. 7
0
//////////////////////////////////////
// File-Download-Function
PSIn TSASFunFPath::ExecSIn(const TStrKdV& FldNmValPrV, 
        const PSAppSrvRqEnv& RqEnv, TStr& ContTypeStr) {

	// construct file name
    TStr FNm = FPath;
    PUrl Url = RqEnv->GetHttpRq()->GetUrl();
    const int PathSegs = Url->GetPathSegs();
    if ((PathSegs == 1) || (PathSegs == 2 && Url->GetPathSeg(1).Empty())) {
        // nothing specified, do the default
        TStr PathSeg = Url->GetPathSeg(0);
        if (PathSeg.LastCh() != '/') { FNm += "/"; }
        FNm += DefaultFNm; 
    } else {
        // extract file name
        for (int PathSegN = 1; PathSegN < PathSegs; PathSegN++) {
            FNm += "/"; FNm += Url->GetPathSeg(PathSegN);
        }
    }

    // get mime-type
	TStr FExt = FNm.GetFExt();
	if (FExt == ".htm") { ContTypeStr = THttp::TextHtmlFldVal; }
	else if (FExt == ".html") { ContTypeStr = THttp::TextHtmlFldVal; }
	else if (FExt == ".js") { ContTypeStr = THttp::TextJavaScriptFldVal; }
	else if (FExt == ".css") { ContTypeStr = THttp::TextCssFldVal; }
	else if (FExt == ".ico") { ContTypeStr = THttp::ImageIcoFldVal; }
	else if (FExt == ".png") { ContTypeStr = THttp::ImagePngFldVal; }
	else if (FExt == ".jpg") { ContTypeStr = THttp::ImageJpgFldVal; }
	else if (FExt == ".jpeg") { ContTypeStr = THttp::ImageJpgFldVal; }
	else if (FExt == ".gif") { ContTypeStr = THttp::ImageGifFldVal; }
	else {
		printf("Unknown MIME type for extension '%s' for file '%s'", FExt.CStr(), FNm.CStr());
		ContTypeStr = THttp::AppOctetFldVal; 
	}

    // return stream to the file
    return TFIn::New(FNm);
}
Esempio n. 8
0
TZipIn::TZipIn(const TStr& FNm, bool& OpenedP) : TSBase(), TSIn(), ZipStdoutRd(NULL), ZipStdoutWr(NULL), SNm(FNm.CStr()),
  FLen(0), CurFPos(0), Bf(NULL), BfC(0), BfL(0) {
  EAssertR(! FNm.Empty(), "Empty file-name.");
  FLen = TZipIn::GetFLen(FNm);
  OpenedP = TFile::Exists(FNm);
  if (OpenedP) {
    #ifdef GLib_WIN
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    // Create a pipe for the child process's STDOUT.
    EAssertR(CreatePipe(&ZipStdoutRd, &ZipStdoutWr, &saAttr, 0), "Stdout pipe creation failed");
    // Ensure the read handle to the pipe for STDOUT is not inherited.
    SetHandleInformation(ZipStdoutRd, HANDLE_FLAG_INHERIT, 0);
    #else
    // no implementation needed
    #endif
    CreateZipProcess(GetCmd(FNm.GetFExt()), FNm);
    Bf = new char[MxBfL]; BfC = BfL=-1;
    FillBf();
  }
}
Esempio n. 9
0
PTb TTb::LoadFile(const TStr& FNm, const TStr& FType, const TStr& MemRep){
  // memory representation
  PTb Tb;
  if (MemRep==""){Tb=PTb(new TGTb());}
  else if (MemRep=="General"){Tb=PTb(new TGTb());}
  else {Fail; return NULL;}
  // file type
  if (FType==""){
    // infer file-type from file-extension
    TStr FExt=FNm.GetFExt().GetUc();
    if (FExt==".TXT"){LoadTxtSpc(FNm, Tb);}
    else if (FExt==".TAB"){LoadTxtTab(FNm, Tb);}
    else if (FExt==".CSV"){LoadTxtCsv(FNm, Tb);}
    else {Fail;}
  } else {
    // use file-type info
    if (FType=="Txt"){LoadTxtSpc(FNm, Tb);}
    else if (FType=="TxtTab"){LoadTxtTab(FNm, Tb);}
    else if (FType=="TxtCsv"){LoadTxtCsv(FNm, Tb);}
    else {Fail;}
  }
  return Tb;
}
Esempio n. 10
0
TStr TZipOut::GetCmd(const TStr& ZipFNm) {
  if (FExtToCmdH.Empty()) FillFExtToCmdH();
  const TStr Ext = ZipFNm.GetFExt().GetLc();
  EAssertR(FExtToCmdH.IsKey(Ext), TStr::Fmt("Unsupported file extension '%s'", Ext.CStr()));
  return FExtToCmdH.GetDat(Ext)+ZipFNm.GetFMid();
}
Esempio n. 11
0
int main(int argc, char* argv[]) {
	Env = TEnv(argc, argv, TNotify::StdNotify);
	Env.PrepArgs(
			TStr::Fmt("Kronecker graphs. build: %s, %s. Time: %s", __TIME__,
					__DATE__, TExeTm::GetCurTm()));
	TExeTm ExeTm;
	Try
		Env = TEnv(argc, argv, TNotify::StdNotify);
		const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "../as20graph.txt",
				"Input graph file (single directed edge per line)");
		TStr OutFNm = Env.GetIfArgPrefixStr("-o:", "", "Output file prefix");
		const TInt NZero = Env.GetIfArgPrefixInt("-n0:", 2,
				"Innitiator matrix size");
		const TStr InitMtx = Env.GetIfArgPrefixStr("-m:", "0.9 0.7; 0.5 0.2",
				"Init Gradient Descent Matrix (R=random)").GetLc();
		const TStr Perm =
				Env.GetIfArgPrefixStr("-p:", "d",
						"Initial node permutation: d:Degree, r:Random, o:Order").GetLc();
		const TInt GradIter = Env.GetIfArgPrefixInt("-gi:", 50,
				"Gradient descent iterations");
		const TFlt LrnRate = Env.GetIfArgPrefixFlt("-l:", 1e-5,
				"Learning rate");
		const TFlt MnStep = Env.GetIfArgPrefixFlt("-mns:", 0.005,
				"Minimum gradient step");
		const TFlt MxStep = Env.GetIfArgPrefixFlt("-mxs:", 0.05,
				"Maximum gradient step");
		const TInt WarmUp = Env.GetIfArgPrefixInt("-w:", 10000,
				"Samples to warm up");
		const TInt NSamples = Env.GetIfArgPrefixInt("-s:", 100000,
				"Samples per gradient estimation");
		//const TInt GradType = Env.GetIfArgPrefixInt("-gt:", 1, "1:Grad1, 2:Grad2");
		const bool ScaleInitMtx = Env.GetIfArgPrefixBool("-sim:", true,
				"Scale the initiator to match the number of edges");
		const TFlt PermSwapNodeProb =
				Env.GetIfArgPrefixFlt("-nsp:", 1.0,
						"Probability of using NodeSwap (vs. EdgeSwap) MCMC proposal distribution");
		if (OutFNm.Empty()) {
			OutFNm = TStr::Fmt("%s-fit%d", InFNm.GetFMid().CStr(), NZero());
		}
		// load graph
		PNGraph G;
		if (InFNm.GetFExt().GetLc() == ".ungraph") {
			TFIn FIn(InFNm);
			G = TSnap::ConvertGraph<PNGraph>(TUNGraph::Load(FIn), true);
		} else if (InFNm.GetFExt().GetLc() == ".ngraph") {
			TFIn FIn(InFNm);
			G = TNGraph::Load(FIn);
		} else {
			G = TSnap::LoadEdgeList<PNGraph>(InFNm, 0, 1);
		}
		// fit
		TKronMtx InitKronMtx =
				InitMtx == "r" ?
						TKronMtx::GetRndMtx(NZero, 0.1) :
						TKronMtx::GetMtx(InitMtx);
		InitKronMtx.Dump("INIT PARAM", true);
		TKroneckerLL KronLL(G, InitKronMtx, PermSwapNodeProb);
		if (ScaleInitMtx) {
			InitKronMtx.SetForEdges(G->GetNodes(), G->GetEdges());
		}
		KronLL.InitLL(G, InitKronMtx);
		InitKronMtx.Dump("SCALED PARAM", true);
		KronLL.SetPerm(Perm.GetCh(0));
		double LogLike = 0;
		//if (GradType == 1) {
		LogLike = KronLL.GradDescent(GradIter, LrnRate, MnStep, MxStep, WarmUp,
				NSamples);
		//} else if (GradType == 2) {
		//  LogLike = KronLL.GradDescent2(GradIter, LrnRate, MnStep, MxStep, WarmUp, NSamples); }
		//else{ Fail; }
		const TKronMtx& FitMtx = KronLL.GetProbMtx();
		FILE *F = fopen(OutFNm.CStr(), "w");
		fprintf(F, "Input\t%s\n", InFNm.CStr());
		TStrV ParamV;
		Env.GetCmLn().SplitOnAllCh(' ', ParamV);
		fprintf(F, "Command line options\n");
		for (int i = 0; i < ParamV.Len(); i++) {
			fprintf(F, "\t%s\n",
					ParamV[i].CStr() + (ParamV[i][0] == '-' ? 1 : 0));
		}
		fprintf(F, "Loglikelihood\t%10.2f\n", LogLike);
		fprintf(F, "Absolute error (based on expected number of edges)\t%f\n",
				KronLL.GetAbsErr());
		fprintf(F, "RunTime\t%g\n", ExeTm.GetSecs());
		fprintf(F, "Estimated initiator\t%s\n", FitMtx.GetMtxStr().CStr());
		fclose(F);

	Catch
	printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(),
			TSecTm::GetCurTm().GetTmStr().CStr());
	return 0;
}
void TMongSrv::OnHttpRq(const int& SockId, const PHttpRq& HttpRq) {
	// check http-request correctness - return if error
	if (!HttpRq->IsOk()) {
		TNotify::OnNotify(Notify, ntInfo, "Web-Server: Bad Http Request.");
		return;
	}
	// check url correctness - return if error
	PUrl RqUrl = HttpRq->GetUrl();
	if (!RqUrl->IsOk()) {
		TNotify::OnNotify(Notify, ntInfo, "Web-Server: Bad Url Requested.");
		return;
	}

	// construct http-response
	PHttpResp HttpResp;
	if (!RqUrl->GetPathStr().Empty()) {
		// get request-file-name
		TStr ExeFPath = TSysProc::GetExeFNm().GetFPath();
		TStr RqFNm = RqUrl->GetPathStr();
		if (RqFNm.LastCh() == '/') {
			RqFNm = RqFNm + "default.htm";
		}
		if ((RqFNm[0] == '/') || (RqFNm[0] == '\\')) {
			RqFNm.DelSubStr(0, 0);
		}
		RqFNm = ExeFPath + RqFNm;
		// open file
		bool RqFOpened = false;
		PSIn RqSIn = TFIn::New(RqFNm, RqFOpened);
		if (!RqFOpened) {
			// prepare default html with time
			TChA HtmlChA;
			HtmlChA += "<html><title>Error - Not Found</title><body>";
			HtmlChA += "File: ";
			HtmlChA += RqUrl->GetPathStr();
			HtmlChA += " not found.";
			HtmlChA += "</body></html>";
			PSIn BodySIn = TMIn::New(HtmlChA);
			HttpResp = PHttpResp(
					new THttpResp(THttp::ErrNotFoundStatusCd,
							THttp::TextHtmlFldVal, false, BodySIn, ""));
		} else {
			// file successfully opened
			PSIn BodySIn = RqSIn;
			if (THttp::IsHtmlFExt(RqFNm.GetFExt())) {
				// send text/html mime type if Html filemg_callback_t
				HttpResp = PHttpResp(
						new THttpResp(THttp::OkStatusCd, THttp::TextHtmlFldVal,
								false, BodySIn, ""));
			} else if (THttp::IsGifFExt(RqFNm.GetFExt())) {
				// send image/gif mime type if Gif file
				HttpResp = PHttpResp(
						new THttpResp(THttp::OkStatusCd, THttp::ImageGifFldVal,
								false, BodySIn, ""));
			} else {
				// send application/octet mime type
				HttpResp = PHttpResp(
						new THttpResp(THttp::OkStatusCd, THttp::AppOctetFldVal,
								false, BodySIn, ""));
			}
		}
	} else {
		// prepare default html with time
		TChA HtmlChA;
		HtmlChA += "<html><title>Welcome to TWebSrv (powered by mongoose 3.1)</title><body>";
		HtmlChA += TSecTm::GetCurTm().GetStr();
		HtmlChA += "</body></html>";
		PSIn BodySIn = TMIn::New(HtmlChA);
		HttpResp = THttpResp::New(THttp::OkStatusCd, THttp::TextHtmlFldVal,
				false, BodySIn);
	}

	// construct & send response
	SendHttpResp(SockId, HttpResp);
	// notify
	if (RqUrl->IsOk()) {
		TChA MsgChA;
		MsgChA += "Web-Server: Request for '";
		MsgChA += RqUrl->GetUrlStr();
		MsgChA += "'.";
		TNotify::OnNotify(Notify, ntInfo, MsgChA);
	}
}
Esempio n. 13
0
bool TFFile::Next(TStr& FNm){
  // if need to recurse
  if (!SubFFile.Empty()){
    if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
    else {SubFFile=NULL;}
  }
  // for all required file-paths
  while (FPathN<FPathV.Len()){
    if ((FPathN!=-1)&&(FindNextFile(FFileDesc->FFileH, &FFileDesc->FDesc))){
      // next file-name available on the current file-path
      TStr FBase=FFileDesc->GetFBase();
      if ((RecurseP)&&(FFileDesc->IsDir())){
        // file-name is directory and recursion is required
        if ((FBase!=".")&&(FBase!="..")){
          // directory is non-trivial - prepare sub-file-find for recursion
          TStr SubFPath=FPathV[FPathN]+FBase;
          TStrV SubFPathV; SubFPathV.Add(SubFPath);
          SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
          if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
          else {SubFFile=NULL;}
        }
      } else {
        // return file-name if fits
        if ((FBase!=".")&&(FBase!="..")){
          FNm=FPathV[FPathN]+FBase;
          TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
          if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
           ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
            CurFNm=FNm; CurFNmN++; return true;}
        }
      }
    } else {
      // close file-find descriptor if needed
      if (FPathN!=-1){
        IAssert(FindClose(FFileDesc->FFileH));
        FFileDesc->FFileH=INVALID_HANDLE_VALUE;
      }
      // find next file existing path from the input list
      while ((++FPathN<FPathV.Len())&&
       ((FFileDesc->FFileH=FindFirstFile((FPathV[FPathN]+"*.*").CStr(),
       &FFileDesc->FDesc))==INVALID_HANDLE_VALUE)){}
      if ((FPathN<FPathV.Len())&&(RecurseP)&&(FFileDesc->IsDir())){
        // file-path found, file-name is directory and recursion is required
        TStr FBase=FFileDesc->GetFBase();
        if ((FBase!=".")&&(FBase!="..")){
          TStr SubFPath=FPathV[FPathN]+FBase;
          TStrV SubFPathV; SubFPathV.Add(SubFPath);
          SubFFile=New(SubFPathV, FExtV, FBaseWc, RecurseP);
          if (SubFFile->Next(FNm)){CurFNm=FNm; CurFNmN++; return true;}
          else {SubFFile=NULL;}
        }
      } else {
        // return file-name if fits
        if (FPathN<FPathV.Len()){
          TStr FBase=FFileDesc->GetFBase();
          if ((FBase!=".")&&(FBase!="..")){
            FNm=FPathV[FPathN]+FBase;
            TStr FExt=FNm.GetFExt(); if (!CsImpP){FExt.ToUc(); FBase.ToUc();}
            if (((FExtV.Empty())||(FExtV.SearchForw(FExt)!=-1))&&
             ((FBaseWc.Empty())||(FBase.IsWcMatch(FBaseWc)))){
              CurFNm=FNm; CurFNmN++; return true;
            }
          }
        }
      }
    }
  }
  // not found
  CurFNm=""; CurFNmN=-1; return false;
}