libdap++
Updated for version 3.8.2
|
00001 // Ancillary.cc 00002 00003 #include "config.h" 00004 00005 //#define DODS_DEBUG 00006 00007 #include "Ancillary.h" 00008 #include "debug.h" 00009 00010 #ifndef WIN32 00011 #ifdef HAVE_UNISTD_H 00012 #include <unistd.h> 00013 #endif 00014 #else 00015 #include <io.h> 00016 #include <fcntl.h> 00017 #include <process.h> 00018 // Win32 does not define this. 08/21/02 jhrg 00019 #define F_OK 0 00020 #endif 00021 00022 namespace libdap { 00023 00068 string 00069 Ancillary::find_ancillary_file( const string &pathname, 00070 const string &ext, 00071 const string &dir, 00072 const string &file ) 00073 { 00074 string::size_type slash = pathname.rfind('/') + 1; 00075 string directory = pathname.substr(0, slash); 00076 string filename = pathname.substr(slash); 00077 string basename = pathname.substr(slash, pathname.rfind('.') - slash); 00078 00079 DBG(cerr << "find ancillary file params: " << pathname << ", " << ext 00080 << ", " << dir << ", " << file << endl); 00081 DBG(cerr << "find ancillary file comp: " << directory << ", " << filename 00082 << ", " << basename << endl); 00083 00084 string dot_ext = "." + ext; 00085 00086 string name = directory + basename + dot_ext; 00087 if (access(name.c_str(), F_OK) == 0) 00088 return name; 00089 00090 name = pathname + dot_ext; 00091 if (access(name.c_str(), F_OK) == 0) 00092 return name; 00093 00094 name = directory + ext; 00095 if (access(name.c_str(), F_OK) == 0) 00096 return name; 00097 00098 name = dir + basename + dot_ext; 00099 if (access(name.c_str(), F_OK) == 0) 00100 return name; 00101 00102 name = directory + file + dot_ext; 00103 if (access(name.c_str(), F_OK) == 0) 00104 return name; 00105 00106 name = dir + file + dot_ext; 00107 if (access(name.c_str(), F_OK) == 0) 00108 return name; 00109 00110 name = dir + ext; 00111 if (access(name.c_str(), F_OK) == 0) 00112 return name; 00113 00114 return ""; 00115 } 00116 00117 // Given a pathname to a datafile, take that pathname apart and look for an 00118 // ancillary file that describes a group of datafiles of which this datafile 00119 // is a member. Assume that groups follow a simple naming convention where 00120 // files use either leading or trailing digits and a common basename to name 00121 // group members. For example, 00stuff.hdf, 01stuff.hdf, 02stuff.hdf, ..., is 00122 // a group and is has `stuff' as its basename. 00123 00137 string 00138 Ancillary::find_group_ancillary_file( const string &name, const string &ext ) 00139 { 00140 // Given /usr/local/data/stuff.01.nc 00141 // pathname = /usr/local/data, filename = stuff.01.nc and 00142 // rootname = stuff.01 00143 string::size_type slash = name.find_last_of('/'); 00144 string dirname = name.substr(0, slash); 00145 string filename = name.substr(slash + 1); 00146 string rootname = filename.substr(0, filename.find_last_of('.')); 00147 00148 // Instead of using regexs, scan the filename for leading and then 00149 // trailing digits. 00150 string::iterator rootname_iter = rootname.begin(); 00151 string::iterator rootname_end_iter = rootname.end(); 00152 if (isdigit(*rootname_iter)) { 00153 while (rootname_iter != rootname_end_iter 00154 && isdigit(*++rootname_iter)) 00155 ; 00156 00157 // We want: new_name = dirname + "/" + <base> + ext but without 00158 // creating a bunch of temp objects. 00159 string new_name = dirname; 00160 new_name.append("/"); 00161 new_name.append(rootname_iter, rootname_end_iter); 00162 new_name.append(ext); 00163 DBG(cerr << "New Name (iter): " << new_name << endl); 00164 if (access(new_name.c_str(), F_OK) == 0) { 00165 return new_name; 00166 } 00167 } 00168 00169 string::reverse_iterator rootname_riter = rootname.rbegin(); 00170 string::reverse_iterator rootname_end_riter = rootname.rend(); 00171 if (isdigit(*rootname_riter)) { 00172 while (rootname_riter != rootname_end_riter 00173 && isdigit(*++rootname_riter)) 00174 ; 00175 string new_name = dirname; 00176 new_name.append("/"); 00177 // I used reverse iters to scan rootname backwards. To avoid 00178 // reversing the fragment between end_riter and riter, pass append 00179 // regular iters obtained using reverse_iterator::base(). See Meyers 00180 // p. 123. 1/22/2002 jhrg 00181 new_name.append(rootname_end_riter.base(), rootname_riter.base()); 00182 new_name.append(ext); 00183 DBG(cerr << "New Name (riter): " << new_name << endl); 00184 if (access(new_name.c_str(), F_OK) == 0) { 00185 return new_name; 00186 } 00187 } 00188 00189 // If we're here either the file does not begin with leading digits or a 00190 // template made by removing those digits was not found. 00191 00192 return ""; 00193 } 00194 00195 void 00196 Ancillary::read_ancillary_das( DAS &das, 00197 const string &pathname, 00198 const string &dir, 00199 const string &file ) 00200 { 00201 string name = find_ancillary_file( pathname, "das", dir, file ) ; 00202 00203 DBG(cerr << "In Ancillary::read_ancillary_dds: name:" << name << endl); 00204 00205 FILE *in = fopen( name.c_str(), "r" ) ; 00206 if( in ) { 00207 das.parse( in ) ; 00208 (void)fclose( in ) ; 00209 #if 0 00210 int res = fclose( in ) ; 00211 if( res ) 00212 DBG(cerr << "Ancillary::read_ancillary_das - Failed to close file " << (void *)in << endl) ; 00213 #endif 00214 } 00215 } 00216 00217 void 00218 Ancillary::read_ancillary_dds( DDS &dds, 00219 const string &pathname, 00220 const string &dir, 00221 const string &file ) 00222 { 00223 string name = find_ancillary_file( pathname, "dds", dir, file ) ; 00224 00225 DBG(cerr << "In Ancillary::read_ancillary_dds: name:" << name << endl); 00226 00227 FILE *in = fopen( name.c_str(), "r" ) ; 00228 if( in ) { 00229 dds.parse( in ) ; 00230 (void)fclose( in ) ; 00231 #if 0 00232 int res = fclose( in ) ; 00233 if( res ) 00234 DBG(cerr << "Ancillary::read_ancillary_das - Failed to close file " << (void *)in << endl) ; 00235 #endif 00236 } 00237 } 00238 00239 } // namespace libdap 00240