10
10
*/
11
11
#include < algorithm>
12
12
#include < cstring>
13
- #include < sstream>
14
13
#include < iostream>
14
+ #include < sstream>
15
15
#include < typeinfo>
16
- #include < variant>
17
16
18
17
#include " eckit/exception/Exceptions.h"
19
18
#include " eckit/log/Log.h"
23
22
#include " nwp_definitions.h"
24
23
25
24
namespace nwp_emulator {
25
+ void codesHandleDeleter::operator ()(codes_handle* h) {
26
+ if (h) {
27
+ codes_handle_delete (h);
28
+ }
29
+ }
30
+
31
+ void fileDeleter::operator ()(FILE* f) {
32
+ if (f) {
33
+ fclose (f);
34
+ }
35
+ }
36
+
26
37
GRIBFileReader::GRIBFileReader (const eckit::PathName& inputPath, size_t rank, size_t root, int stepCountLimit) :
27
38
rank_ (rank), root_(root), DataReader(stepCountLimit) {
28
39
if (rank_ != root_) {
@@ -45,10 +56,10 @@ GRIBFileReader::GRIBFileReader(const eckit::PathName& inputPath, size_t rank, si
45
56
// 2. Field names & metadata (parameters)
46
57
std::string paramBuffer;
47
58
if (rank_ == root_) {
48
- for (const auto & param: params_) {
59
+ for (const auto & param : params_) {
49
60
paramBuffer += param + " ;" ;
50
61
}
51
- paramBuffer.pop_back (); // remove last ';' separator
62
+ paramBuffer.pop_back (); // remove last ';' separator
52
63
}
53
64
size_t paramSize = paramBuffer.size ();
54
65
eckit::mpi::comm ().broadcast (paramSize, root_);
@@ -125,7 +136,7 @@ void GRIBFileReader::setupReader(const eckit::PathName& inputPath, bool isRoot)
125
136
char buffer[64 ];
126
137
size_t size = sizeof (buffer);
127
138
// 1. Lock the grid name from the passed GRIB file
128
- if (codes_get_string (grib_ , " gridName" , buffer, &size) == GRIB_NOT_FOUND) {
139
+ if (codes_get_string (grib () , " gridName" , buffer, &size) == GRIB_NOT_FOUND) {
129
140
eckit::Log::error () << " Grid type unsupported at the moment, exit" << std::endl;
130
141
eckit::mpi::comm ().abort (1 );
131
142
}
@@ -135,15 +146,11 @@ void GRIBFileReader::setupReader(const eckit::PathName& inputPath, bool isRoot)
135
146
std::string paramMd, _;
136
147
eckit::Log::info () << " Params (name,levtype,level) : " ;
137
148
for (int i = 0 ; i < count_ - 1 ; ++i) {
138
- int err;
139
149
readMsgMetadata (_, paramMd);
140
150
params_.push_back (paramMd);
141
151
eckit::Log::info () << params_[i] << " ; " ;
142
- codes_handle_delete (grib_);
143
- grib_ = codes_handle_new_from_file (nullptr , currentFile_, PRODUCT_GRIB, &err);
144
- if (!grib_) {
145
- eckit::Log::error () << " Could not create grib handle. Error: " << err << " Check source file " << srcPath
146
- << std::endl;
152
+ if (!resetGribHandle ()) {
153
+ eckit::Log::error () << " Check source file " << srcPath << std::endl;
147
154
eckit::mpi::comm ().abort (1 );
148
155
}
149
156
}
@@ -172,26 +179,22 @@ void GRIBFileReader::validateSrcFiles(bool isRoot) {
172
179
fileParams.clear ();
173
180
openGribFile (filename, true );
174
181
for (int i = 0 ; i < count_ - 1 ; ++i) {
175
- int err;
176
182
readMsgMetadata (gridName, paramMd);
177
183
if (gridName != gridName_) {
178
- eckit::Log::error () << " Grid in " << filename << " is different from setup ("
179
- << gridName_ << " ), exit..." << std::endl;
184
+ eckit::Log::error () << " Grid in " << filename << " is different from setup (" << gridName_
185
+ << " ), exit..." << std::endl;
180
186
eckit::mpi::comm ().abort (1 );
181
187
}
182
188
fileParams.push_back (paramMd);
183
- codes_handle_delete (grib_);
184
- grib_ = codes_handle_new_from_file (nullptr , currentFile_, PRODUCT_GRIB, &err);
185
- if (!grib_) {
186
- eckit::Log::error () << " Could not create grib handle. Error: " << err << " Check source file "
187
- << filename << std::endl;
189
+ if (!resetGribHandle ()) {
190
+ eckit::Log::error () << " Check source file " << filename << std::endl;
188
191
eckit::mpi::comm ().abort (1 );
189
192
}
190
193
}
191
- readMsgMetadata (gridName, paramMd); // read the last message in the file
194
+ readMsgMetadata (gridName, paramMd); // read the last message in the file
192
195
if (gridName != gridName_) {
193
- eckit::Log::error () << " Grid in " << filename << " is different from setup ("
194
- << gridName_ << " ), exit... " << std::endl;
196
+ eckit::Log::error () << " Grid in " << filename << " is different from setup (" << gridName_ << " ), exit... "
197
+ << std::endl;
195
198
eckit::mpi::comm ().abort (1 );
196
199
}
197
200
fileParams.push_back (paramMd);
@@ -210,7 +213,7 @@ void GRIBFileReader::readMsgMetadata(std::string& gridName, std::string& paramMd
210
213
char buffer[64 ];
211
214
size_t size = sizeof (buffer);
212
215
gridName = " " ;
213
- int gridStatus = codes_get_string (grib_ , " gridName" , buffer, &size);
216
+ int gridStatus = codes_get_string (grib () , " gridName" , buffer, &size);
214
217
if (gridStatus != GRIB_NOT_FOUND) {
215
218
gridName = std::string (buffer);
216
219
}
@@ -219,7 +222,7 @@ void GRIBFileReader::readMsgMetadata(std::string& gridName, std::string& paramMd
219
222
for (const auto & keyword : keywords) {
220
223
std::memset (buffer, 0 , 64 );
221
224
size = sizeof (buffer);
222
- codes_get_string (grib_ , keyword, buffer, &size);
225
+ codes_get_string (grib () , keyword, buffer, &size);
223
226
paramMd.append (buffer);
224
227
paramMd.append (" ," ); // separator
225
228
}
@@ -234,7 +237,7 @@ bool GRIBFileReader::openGribFile(const eckit::PathName& path, bool exit) {
234
237
// No check for existence here because the paths passed belong to the src dir
235
238
// It is assumed they will not be deleted during runtime
236
239
// No check for file format as checked during construction
237
- currentFile_ = fopen (path.asString ().c_str (), " rb" );
240
+ currentFile_. reset ( fopen (path.asString ().c_str (), " rb" ) );
238
241
if (!currentFile_) {
239
242
eckit::Log::error () << " Could not open file " << path << std::endl;
240
243
if (exit ) {
@@ -243,31 +246,33 @@ bool GRIBFileReader::openGribFile(const eckit::PathName& path, bool exit) {
243
246
return false ; // defer error handling
244
247
}
245
248
index_ = 0 ;
246
- codes_count_in_file (nullptr , currentFile_, &count_);
247
- int err;
248
- grib_ = codes_handle_new_from_file (nullptr , currentFile_, PRODUCT_GRIB, &err);
249
- if (!grib_) {
250
- eckit::Log::error () << " Could not create grib handle. Error: " << err << std::endl;
249
+ codes_count_in_file (nullptr , currentFile (), &count_);
250
+ if (!resetGribHandle ()) {
251
251
if (exit ) {
252
252
eckit::mpi::comm ().abort (1 );
253
253
}
254
- return false ; // defer error handling
254
+ return false ;
255
255
}
256
256
return true ;
257
257
}
258
258
259
- void GRIBFileReader::closeGribFile () {
260
- if (grib_) {
261
- codes_handle_delete (grib_);
262
- }
263
- if (currentFile_) {
264
- fclose (currentFile_);
259
+ bool GRIBFileReader::resetGribHandle () {
260
+ int err;
261
+ // This calls the deleter of the previous handle first
262
+ grib_.reset (codes_handle_new_from_file (nullptr , currentFile (), PRODUCT_GRIB, &err));
263
+ if (!grib_) {
264
+ eckit::Log::error () << " Could not create grib handle. Error: " << err << std::endl;
265
+ return false ;
265
266
}
267
+ return true ;
268
+ }
269
+
270
+ void GRIBFileReader::closeGribFile () {
266
271
count_ = 0 ;
267
272
index_ = 0 ;
268
- // To avoid segfault at destruction if they have already been dereferenced
269
- currentFile_ = nullptr ;
270
- grib_ = nullptr ;
273
+ // Calls the custom destructors
274
+ currentFile_. reset ( nullptr ) ;
275
+ grib_. reset ( nullptr ) ;
271
276
}
272
277
273
278
bool GRIBFileReader::done () {
@@ -307,28 +312,21 @@ bool GRIBFileReader::nextMessage(std::string& shortName, std::string& levtype, s
307
312
std::getline (ss, level, ' ,' );
308
313
309
314
size_t nbOfValues;
310
- codes_get_size (grib_ , " values" , &nbOfValues);
315
+ codes_get_size (grib () , " values" , &nbOfValues);
311
316
data.resize (nbOfValues);
312
317
if constexpr (std::is_same_v<FIELD_TYPE_REAL, double >) {
313
318
ASSERT ((std::is_same_v<FIELD_TYPE_REAL, double >));
314
- codes_get_double_array (grib_ , " values" , reinterpret_cast <double *>(data.data ()), &nbOfValues);
319
+ codes_get_double_array (grib () , " values" , reinterpret_cast <double *>(data.data ()), &nbOfValues);
315
320
}
316
321
else {
317
322
ASSERT ((std::is_same_v<FIELD_TYPE_REAL, float >));
318
- codes_get_float_array (grib_ , " values" , reinterpret_cast <float *>(data.data ()), &nbOfValues);
323
+ codes_get_float_array (grib () , " values" , reinterpret_cast <float *>(data.data ()), &nbOfValues);
319
324
}
320
325
}
321
326
++index_;
322
327
eckit::mpi::comm ().broadcast (count_, root_);
323
328
if (rank_ == root_ && index_ < count_) {
324
- // Load the next message
325
- int err;
326
- codes_handle_delete (grib_);
327
- grib_ = codes_handle_new_from_file (nullptr , currentFile_, PRODUCT_GRIB, &err);
328
- if (!grib_) {
329
- eckit::Log::error () << " Could not create grib handle. Error: " << err << " Skipping..." << std::endl;
330
- return false ;
331
- }
329
+ return resetGribHandle (); // Load the next message
332
330
}
333
331
return true ;
334
332
}
0 commit comments