1 /*
2    This file is part of the BOLT-LMM linear mixed model software package
3    developed by Po-Ru Loh.  Copyright (C) 2014-2019 Harvard University.
4 
5    This program is free software: you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation, either version 3 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef FILEUTILS_HPP
20 #define FILEUTILS_HPP
21 
22 #include <vector>
23 #include <string>
24 #include <iostream>
25 #include <fstream>
26 
27 #include "StringUtils.hpp"
28 
29 #include <boost/iostreams/filtering_stream.hpp>
30 
31 namespace FileUtils {
32 
33   void openOrExit(std::ifstream &stream, const std::string &file,
34 		  std::ios_base::openmode mode=std::ios::in);
35 
36   void openWritingOrExit(std::ofstream &stream, const std::string &file,
37 			 std::ios_base::openmode mode=std::ios::out);
38 
39   void requireEmptyOrReadable(const std::string &file);
40 
41   void requireEachEmptyOrReadable(const std::vector <std::string> &fileList);
42 
43   void requireEmptyOrWriteable(const std::string &file);
44 
45   std::vector <std::string> parseHeader(const std::string &fileName,
46 					const std::string &delimiters);
47 
48   int lookupColumnInd(const std::string &fileName, const std::string &delimiters,
49 		      const std::string &columnName);
50 
51   double readDoubleNanInf(std::istream &stream);
52 
53   std::vector < std::pair <std::string, std::string> > readFidIids(const std::string &file);
54   std::vector < std::pair <std::string, std::string> > readSampleIDs(const std::string &file);
55 
56   class AutoGzIfstream {
57     boost::iostreams::filtering_istream boost_in;
58     std::ifstream fin;
59   public:
60     static int lineCount(const std::string &file);
61 
62     void openOrExit(const std::string &file, std::ios_base::openmode mode=std::ios::in);
63     void close();
operator >>(T & x)64     template <class T> AutoGzIfstream& operator >> (T &x) {
65       boost_in >> x;
66       return *this;
67     }
68     operator bool() const;
69     AutoGzIfstream& read(char *s, std::streamsize n);
70     std::streamsize gcount() const;
71     int get();
72     double readDoubleNanInf();
73     void clear();
74     AutoGzIfstream& seekg(std::streamoff off, std::ios_base::seekdir way);
75     friend AutoGzIfstream& getline(AutoGzIfstream& in, std::string &s);
76   };
77 
78   AutoGzIfstream& getline(AutoGzIfstream& in, std::string &s);
79 
80   class AutoGzOfstream {
81     boost::iostreams::filtering_ostream boost_out;
82     std::ofstream fout;
83   public:
84     void openOrExit(const std::string &file, std::ios_base::openmode mode=std::ios::out);
85     void close();
operator <<(const T & x)86     template <class T> AutoGzOfstream& operator << (const T &x) {
87       boost_out << x;
88       if (boost_out.fail()) {
89 	std::cerr << "ERROR: File write failed" << std::endl;
90 	exit(1);
91       }
92       return *this;
93     }
94     AutoGzOfstream& operator << (std::ostream&(*manip)(std::ostream&));
95     void unsetf(std::ios_base::fmtflags);
96     operator bool() const;
97   };
98 
99   int checkBgenSample(const std::string &bgenFile, const std::string &sampleFile, int Nautosomes);
100 
101 }
102 
103 #endif
104