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