ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/io/ifstrstream.cpp
Revision: 1874
Committed: Wed May 15 15:09:35 2013 UTC (11 years, 11 months ago) by gezelter
File size: 9957 byte(s)
Log Message:
Fixed a bunch of cppcheck warnings.

File Contents

# User Rev Content
1 gezelter 1627 /*
2     * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     *
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31     *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38 gezelter 1850 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 gezelter 1665 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 gezelter 1627 */
42    
43     /**
44 gezelter 1808 * @file ifstrstream.cpp
45 gezelter 1627 * @author Teng Lin
46     * @date 10/14/2004
47     * @version 1.0
48     */
49    
50     #include "io/ifstrstream.hpp"
51    
52     #ifdef IS_MPI
53     #include <mpi.h>
54     #endif
55    
56     namespace OpenMD {
57    
58     /** Constructs an object of class ifstream. */
59     #ifdef IS_MPI
60     ifstrstream::ifstrstream()
61     : std::basic_istream<char, std::char_traits<char> >(0),
62     internalStringBuf_(), isRead(false) {
63     this->init(&internalStringBuf_);
64     }
65     #else
66     ifstrstream::ifstrstream()
67     : std::basic_istream<char, std::char_traits<char> >(0),
68     internalFileBuf_(), isRead(false) {
69     this->init(&internalFileBuf_);
70     }
71     #endif
72    
73     /**
74     * Explicit constructor
75 gezelter 1808 * @param filename String containing the name of the file to be opened
76     * @param mode Flags describing the requested i/o mode for the file, default value is ios_base::in
77     * @param checkFilename Flags indicating checking the file name in parallel
78 gezelter 1627 */
79     #ifdef IS_MPI
80     ifstrstream::ifstrstream(const char* filename, std::ios_base::openmode mode, bool checkFilename)
81     : std::basic_istream<char, std::char_traits<char> >(0),
82     internalStringBuf_(), isRead(false) {
83     this->init(&internalStringBuf_);
84     isRead = internalOpen(filename, mode | std::ios_base::in, checkFilename);
85     }
86     #else
87     ifstrstream::ifstrstream(const char* filename, std::ios_base::openmode mode, bool checkFilename)
88     : std::basic_istream<char, std::char_traits<char> >(0),
89     internalFileBuf_(), isRead(false) {
90    
91     this->init(&internalFileBuf_);
92     isRead = internalOpen(filename, mode | std::ios_base::in, checkFilename);
93     }
94     #endif
95     /**
96     * virtual destructor will close the file(in single mode) and clear the stream buffer
97     */
98     ifstrstream::~ifstrstream(){
99     close();
100     }
101    
102     /**
103     * Opens a file and associats a buffer with the specified file to perform the i/o operations
104     * (single mode). Master reads a file and brocasts its content to the other slave nodes. After
105     * brocasting, every nodes fall back to stringstream (parallel mode).
106 gezelter 1808 * @param filename String containing the name of the file to be opened
107     * @param mode Flags describing the requested i/o mode for the file
108     * @param checkFilename Flags indicating checking the file name in parallel
109 gezelter 1627 */
110     void ifstrstream::open(const char* filename, std::ios_base::openmode mode, bool checkFilename){
111    
112     if (!isRead ) {
113     isRead = internalOpen(filename, mode, checkFilename);
114     }
115     }
116    
117     /**
118     * Tests if the stream is currently associated with a valid buffer.
119     * @return true if a file has successfully been opened (single mode) or the whole file is read
120     * and spreaded among all of the processors (parallel mode), otherwise false is returned
121     */
122     bool ifstrstream::is_open ( ) {
123     #ifdef IS_MPI
124     return isRead;
125     #else
126     //single version fall back to ifstream
127     return internalFileBuf_.is_open();
128     #endif
129     }
130    
131     /**
132     * In single mode, closes a file. The stream's file buffer is
133     * released from its association with the currently open file. In
134     * parallel mode, clean the
135     */
136     void ifstrstream::close() {
137     #ifndef IS_MPI
138     //single version fall back to ifstream
139     if (!internalFileBuf_.close())
140     this->setstate(std::ios_base::failbit);
141     #endif
142    
143     isRead = false;
144     }
145    
146     /**
147     * Gets the stream buffer object associated with the stream
148     * @return A pointer to the stream buffer object(filebuf in single
149     * mode, stringbuf in parallel mode) associated with the stream.
150     */
151     std::basic_streambuf<char, std::char_traits<char> >* ifstrstream::rdbuf() {
152     #ifdef IS_MPI
153     return static_cast<_StringBuf*>(&internalStringBuf_);
154     #else
155     return static_cast<_FileBuf*>(&internalFileBuf_);
156     #endif
157     }
158    
159     /**
160     * Internal function used to open the file
161     * @return true if succesfully opens a file (single mode) or gets the file content (parallel mode)
162     * otherwise return false
163 gezelter 1808 * @param filename String containing the name of the file to be opened
164     * @param mode Flags describing the requested i/o mode for the file
165     * @param checkFilename Flags indicating checking the file name in parallel
166 gezelter 1627 * @todo use try - catch syntax to make the program more readable
167     */
168    
169     bool ifstrstream::internalOpen(const char* filename, std::ios_base::openmode mode, bool checkFilename){
170    
171     #ifdef IS_MPI
172 gezelter 1798 //int commStatus;
173 gezelter 1627 long fileSize;
174     char* fbuf;
175     int filenameLen;
176     int diffFilename;
177     int error;
178     int myRank;
179     int masterNode;
180    
181 gezelter 1798 myRank = MPI::COMM_WORLD.Get_rank();
182 gezelter 1627 masterNode = 0;
183    
184     if (myRank == masterNode) {
185    
186     if (checkFilename) {
187    
188     //check the filename is the same
189     filenameLen = strlen(filename);
190 gezelter 1798 MPI::COMM_WORLD.Bcast(&filenameLen, 1, MPI::INT, masterNode);
191     MPI::COMM_WORLD.Bcast((void*)filename, filenameLen, MPI::CHAR,
192     masterNode);
193 gezelter 1627
194     diffFilename = 0;
195 gezelter 1798 MPI::COMM_WORLD.Allreduce(&diffFilename, &error, 1, MPI::INT, MPI::SUM);
196    
197 gezelter 1627 //if file names are different just return false
198     if (error > 0)
199     return false;
200     }
201    
202     std::ifstream fin(filename, mode);
203    
204     if (fin.is_open()) {
205    
206     fin.seekg(0, std::ios::end);
207     fileSize = fin.tellg();
208     fin.seekg(0, std::ios::beg);
209    
210     // '\0' need one more char
211     fbuf = new char[fileSize+1];
212    
213     assert(fbuf != 0);
214    
215     fin.read(fbuf, fileSize);
216    
217     if (fin.fail())
218     fileSize = FileIOError;
219    
220 gezelter 1798 //broadcast the file size
221     MPI::COMM_WORLD.Bcast(&fileSize, 1, MPI::LONG, masterNode);
222 gezelter 1627
223     if (fileSize < 0) {
224     fin.close();
225 gezelter 1874 delete[] fbuf;
226 gezelter 1627
227     return false;
228     }
229    
230 gezelter 1798 // make a c-style std::string and broadcast it
231 gezelter 1627 fbuf[fileSize] = '\0';
232 gezelter 1798 MPI::COMM_WORLD.Bcast(fbuf, fileSize + 1, MPI::CHAR, masterNode);
233 gezelter 1627
234     //close the file and delete the buffer
235     fin.close();
236     internalStringBuf_.str(fbuf);
237 gezelter 1874 delete[] fbuf;
238 gezelter 1627 }else{
239     fileSize = FileNotExists;
240 gezelter 1798 MPI::COMM_WORLD.Bcast(&fileSize, 1, MPI::LONG, masterNode);
241 gezelter 1627 return false;
242     }
243    
244     } else{ //slave nodes
245    
246     //check file name
247     if (checkFilename) {
248 gezelter 1798 MPI::COMM_WORLD.Bcast(&filenameLen, 1, MPI::INT, masterNode);
249 gezelter 1627
250     char * masterFilename = new char[filenameLen];
251 gezelter 1798 MPI::COMM_WORLD.Bcast(masterFilename, filenameLen, MPI::CHAR,
252     masterNode);
253 gezelter 1627
254     if( strcmp(masterFilename, filename) == 0)
255     diffFilename = 0;
256     else
257     diffFilename = 1;
258    
259 gezelter 1874 delete[] masterFilename;
260 gezelter 1627
261 gezelter 1798 MPI::COMM_WORLD.Allreduce(&diffFilename, &error, 1, MPI::INT, MPI::SUM);
262 gezelter 1627
263     if (error > 0)
264     return false;
265     }
266     //get file size
267 gezelter 1798 MPI::COMM_WORLD.Bcast(&fileSize, 1, MPI::LONG, masterNode);
268 gezelter 1627
269     if (fileSize >= 0 ) {
270     fbuf = new char[fileSize+1];
271     assert(fbuf);
272    
273     //receive file content
274 gezelter 1798 MPI::COMM_WORLD.Bcast(fbuf, fileSize + 1, MPI::CHAR, masterNode);
275 gezelter 1627
276     internalStringBuf_.str(fbuf);
277     delete [] fbuf;
278    
279     } else if (fileSize == FileNotExists ) {
280     return false;
281    
282     } else if (fileSize == FileIOError ) {
283     return false;
284     }
285     }
286    
287     #else
288     //in single version, fall back to ifstream
289     if (!internalFileBuf_.open(filename, mode)) {
290     this->setstate(std::ios_base::failbit);
291     return false;
292     }
293    
294     #endif
295     this->clear();
296     return true;
297     }
298     }

Properties

Name Value
svn:eol-style native