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

# Content
1 /*
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 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 */
42
43 /**
44 * @file ifstrstream.cpp
45 * @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 * @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 */
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 * @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 */
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 * @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 * @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 //int commStatus;
173 long fileSize;
174 char* fbuf;
175 int filenameLen;
176 int diffFilename;
177 int error;
178 int myRank;
179 int masterNode;
180
181 myRank = MPI::COMM_WORLD.Get_rank();
182 masterNode = 0;
183
184 if (myRank == masterNode) {
185
186 if (checkFilename) {
187
188 //check the filename is the same
189 filenameLen = strlen(filename);
190 MPI::COMM_WORLD.Bcast(&filenameLen, 1, MPI::INT, masterNode);
191 MPI::COMM_WORLD.Bcast((void*)filename, filenameLen, MPI::CHAR,
192 masterNode);
193
194 diffFilename = 0;
195 MPI::COMM_WORLD.Allreduce(&diffFilename, &error, 1, MPI::INT, MPI::SUM);
196
197 //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 //broadcast the file size
221 MPI::COMM_WORLD.Bcast(&fileSize, 1, MPI::LONG, masterNode);
222
223 if (fileSize < 0) {
224 fin.close();
225 delete[] fbuf;
226
227 return false;
228 }
229
230 // make a c-style std::string and broadcast it
231 fbuf[fileSize] = '\0';
232 MPI::COMM_WORLD.Bcast(fbuf, fileSize + 1, MPI::CHAR, masterNode);
233
234 //close the file and delete the buffer
235 fin.close();
236 internalStringBuf_.str(fbuf);
237 delete[] fbuf;
238 }else{
239 fileSize = FileNotExists;
240 MPI::COMM_WORLD.Bcast(&fileSize, 1, MPI::LONG, masterNode);
241 return false;
242 }
243
244 } else{ //slave nodes
245
246 //check file name
247 if (checkFilename) {
248 MPI::COMM_WORLD.Bcast(&filenameLen, 1, MPI::INT, masterNode);
249
250 char * masterFilename = new char[filenameLen];
251 MPI::COMM_WORLD.Bcast(masterFilename, filenameLen, MPI::CHAR,
252 masterNode);
253
254 if( strcmp(masterFilename, filename) == 0)
255 diffFilename = 0;
256 else
257 diffFilename = 1;
258
259 delete[] masterFilename;
260
261 MPI::COMM_WORLD.Allreduce(&diffFilename, &error, 1, MPI::INT, MPI::SUM);
262
263 if (error > 0)
264 return false;
265 }
266 //get file size
267 MPI::COMM_WORLD.Bcast(&fileSize, 1, MPI::LONG, masterNode);
268
269 if (fileSize >= 0 ) {
270 fbuf = new char[fileSize+1];
271 assert(fbuf);
272
273 //receive file content
274 MPI::COMM_WORLD.Bcast(fbuf, fileSize + 1, MPI::CHAR, masterNode);
275
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