1 #include "streamFuns.h"
2 #include "ErrorWarning.h"
3 #include <fstream>
4 #include <sys/statvfs.h>
5 #include <sys/stat.h>
6 #include <stdio.h>
7 #define fstream_Chunk_Max 2147483647
8 #include <cstring>
9 
createDirectory(const string dirPathIn,const mode_t dirPerm,const string dirParameter,Parameters & P)10 void createDirectory(const string dirPathIn, const mode_t dirPerm, const string dirParameter, Parameters &P)
11 {
12 	string dirPath = dirPathIn.substr(0,dirPathIn.find_last_of('/')+1);
13 	if (mkdir(dirPath.c_str(), dirPerm) == -1) {
14 		if ( errno == EEXIST ) {//directory exists
15 			P.inOut->logMain << dirParameter << " directory exists and will be overwritten: " << dirPath <<std::endl;
16 		} else {//other error
17 			//will try to create parent directories
18 			size_t i1=dirPath.find_first_of('/',1);
19 			while (i1<dirPath.size()) {
20 				string dirPath1=dirPath.substr(0,i1);
21 				if (mkdir(dirPath1.c_str(), dirPerm) == -1) {
22 					if ( !(errno == EEXIST) ) {//error
23 				        exitWithError("EXITING because of fatal OUTPUT FILE error: could not create output directory: " + dirPath1 +
24 				        			  " for " + dirParameter + " " + dirPathIn +
25 									  "\n ERROR: " + strerror(errno) +
26 				                      "\nSOLUTION: check the path and permissions.\n",
27 				                       std::cerr, P.inOut->logMain, EXIT_CODE_PARAMETER, P);
28 					};
29 				};
30 				i1=dirPath.find_first_of('/',i1+1);
31 			};
32 			P.inOut->logMain << dirParameter << " directory and its parents created: " << dirPath <<std::endl;
33 		};
34     } else {
35     	P.inOut->logMain << dirParameter << " directory created: " << dirPath <<std::endl;
36     };
37 };
38 
fstreamReadBig(std::ifstream & S,char * A,unsigned long long N)39 unsigned long long fstreamReadBig(std::ifstream &S, char* A, unsigned long long N) {
40     unsigned long long C=0;
41     for (unsigned long long ii=0; ii<N/fstream_Chunk_Max; ii++) {
42         S.read(A+C,fstream_Chunk_Max);
43         C+=S.gcount();
44         if (!S.good()) break;
45     };
46     S.read(A+C,N%fstream_Chunk_Max);
47     C+=S.gcount();
48     return C;
49 };
50 
fstreamWriteBig(std::ofstream & S,char * A,unsigned long long N,std::string fileName,std::string errorID,Parameters & P)51 void fstreamWriteBig(std::ofstream &S, char* A, unsigned long long N, std::string fileName, std::string errorID, Parameters &P) {
52 
53     struct statvfs statvfsBuf;
54     statvfs(fileName.c_str(), &statvfsBuf);
55     P.inOut->logMain << "Writing " << N << " bytes into " <<fileName << " ; empty space on disk = " << statvfsBuf.f_bavail * statvfsBuf.f_bsize <<" bytes ..." <<flush;
56 
57     unsigned long long C=0;
58     unsigned long long iC;
59     for (iC=0; iC<N/fstream_Chunk_Max; iC++) {
60         S.write(A+C,fstream_Chunk_Max);
61         C+=fstream_Chunk_Max;
62     };
63     if (!S.fail()) S.write(A+C,N%fstream_Chunk_Max);
64     if (S.fail()) {//failed to write
65 
66         struct statvfs statvfsBuf;
67         statvfs(fileName.c_str(), &statvfsBuf);
68 
69 //         system(( "ls -lL "+ P.pGe.gDir + " > "+ P.pGe.gDir +"/error.info 2>&1").c_str());
70 //         ifstream error_info((P.pGe.gDir +"/error.info").c_str());
71 //         P.inOut->logMain <<error_info.rdbuf();
72 
73         struct stat statBuf;
74         stat(fileName.c_str(), &statBuf);
75 
76         remove(fileName.c_str());
77 
78         ostringstream errOut;
79         errOut << errorID<<": exiting because of *OUTPUT FILE* error: could not write the output file "<< fileName <<"\n";
80         errOut << "fail()=" <<S.fail() <<" ; bad()="<< S.bad()<<"\n";
81         errOut << "Error while trying to write chunk # " << iC << "; "<< C << " bytes\n";
82         errOut << "File size full = "<< N <<" bytes\n";
83         errOut << "File size on disk = " << statBuf.st_size<<" bytes\n";
84         errOut << "Solution: check that you have enough space on the disk\n";
85         errOut << "Empty space on disk = " << statvfsBuf.f_bavail * statvfsBuf.f_bsize <<" bytes\n";
86         exitWithError(errOut.str(),std::cerr, P.inOut->logMain, EXIT_CODE_FILE_WRITE, P);
87     };
88     P.inOut->logMain << " done\n" <<flush;
89 };
90 
ofstrOpen(std::string fileName,std::string errorID,Parameters & P)91 std::ofstream &ofstrOpen (std::string fileName, std::string errorID, Parameters &P) {//open file 'fileName', generate error if cannot open
92     std::ofstream & ofStream = *new std::ofstream(fileName.c_str(), std::fstream::out | std::fstream::trunc);
93     if (ofStream.fail()) {//
94         ostringstream errOut;
95         errOut << errorID<<": exiting because of *OUTPUT FILE* error: could not create output file "<< fileName <<"\n";
96         errOut << "SOLUTION: check that the path exists and you have write permission for this file. Also check ""ulimit -n"" and increase it to allow more open files.\n";
97         exitWithError(errOut.str(),std::cerr, P.inOut->logMain, EXIT_CODE_FILE_OPEN, P);
98     };
99     return ofStream;
100 };
101 
fstrOpen(std::string fileName,std::string errorID,Parameters & P,bool flagDelete)102 std::fstream &fstrOpen (std::string fileName, std::string errorID, Parameters &P, bool flagDelete) {//open file 'fileName', generate error if cannot open
103     //std::fstream &fStream = *new std::fstream(fileName.c_str(), std::fstream::in | std::fstream::out );
104     //std::fstream &fStream = *new std::fstream(fileName.c_str(), std::fstream::in | std::fstream::out | std::fstream::trunc);
105 
106     std::fstream *fStreamP;
107     if (flagDelete) {//truncate the file if it exists
108         fStreamP = new std::fstream(fileName.c_str(), std::fstream::in | std::fstream::out | std::fstream::trunc);
109     } else {//try to open exising file
110         fStreamP=new std::fstream(fileName.c_str(), std::fstream::in | std::fstream::out );
111         if (fStreamP->fail()) //did not work <= file does not exist => open with trunc (the above command does not work on new file)
112             fStreamP = new std::fstream(fileName.c_str(), std::fstream::in | std::fstream::out | std::fstream::trunc);
113     };
114 
115     if (fStreamP->fail()) {//
116         ostringstream errOut;
117         errOut << errorID<<": exiting because of *OUTPUT FILE* error: could not create input/output file "<< fileName <<"\n";
118         errOut << "Solution: check that the path exists and you have write permission for this file\n";
119         exitWithError(errOut.str(),std::cerr, P.inOut->logMain, EXIT_CODE_FILE_OPEN, P);
120     };
121     return *fStreamP;
122 };
123 
ifstrOpen(std::string fileName,std::string errorID,std::string solutionString,Parameters & P)124 std::ifstream & ifstrOpen (std::string fileName, std::string errorID, std::string solutionString, Parameters &P) {
125     //open file 'fileName', generate error if cannot open
126     std::ifstream & ifStream = *new std::ifstream(fileName.c_str());
127     if (ifStream.fail()) {//
128         ostringstream errOut;
129         errOut << errorID<<": exiting because of *INPUT FILE* error: could not open input file "<< fileName <<"\n";
130         errOut << "Solution: check that the file exists and you have read permission for this file\n";
131         if (solutionString.size()>0) {
132             errOut << "          "<< solutionString <<"\n";
133         };
134         exitWithError(errOut.str(),std::cerr, P.inOut->logMain, EXIT_CODE_FILE_OPEN, P);
135     };
136     return ifStream;
137 };
138 
ifstrOpenGenomeFile(std::string fileName,std::string errorID,Parameters & P)139 ifstream & ifstrOpenGenomeFile (std::string fileName, std::string errorID, Parameters &P) {
140      //open one of the genome files
141      return ifstrOpen(P.pGe.gDir+"/"+fileName, errorID,  "if this file is missing from the genome directory, you will need to *re-generate the genome*", P);
142 };
143 
copyFile(string fileIn,string fileOut)144 void copyFile(string fileIn, string fileOut)
145 {//copy fileIn into FileOut
146     std::ifstream  src(fileIn, std::ios::binary);
147     std::ofstream  dst(fileOut,   std::ios::binary);
148     dst << src.rdbuf();
149 };
150