libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
Ancillary.cc
1 // Ancillary.cc
2 
3 #include "config.h"
4 
5 //#define DODS_DEBUG
6 
7 #include "Ancillary.h"
8 #include "debug.h"
9 
10 #ifndef WIN32
11 #ifdef HAVE_UNISTD_H
12 #include <unistd.h>
13 #endif
14 #else
15 #include <io.h>
16 #include <fcntl.h>
17 #include <process.h>
18 // Win32 does not define this. 08/21/02 jhrg
19 #define F_OK 0
20 #endif
21 
22 namespace libdap {
23 
68 string
69 Ancillary::find_ancillary_file( const string &pathname,
70  const string &ext,
71  const string &dir,
72  const string &file )
73 {
74  string::size_type slash = pathname.rfind('/') + 1;
75  string directory = pathname.substr(0, slash);
76  string filename = pathname.substr(slash);
77  string basename = pathname.substr(slash, pathname.rfind('.') - slash);
78 
79  DBG(cerr << "find ancillary file params: " << pathname << ", " << ext
80  << ", " << dir << ", " << file << endl);
81  DBG(cerr << "find ancillary file comp: " << directory << ", " << filename
82  << ", " << basename << endl);
83 
84  string dot_ext = "." + ext;
85 
86  string name = directory + basename + dot_ext;
87  if (access(name.c_str(), F_OK) == 0)
88  return name;
89 
90  name = pathname + dot_ext;
91  if (access(name.c_str(), F_OK) == 0)
92  return name;
93 
94  name = directory + ext;
95  if (access(name.c_str(), F_OK) == 0)
96  return name;
97 
98  name = dir + basename + dot_ext;
99  if (access(name.c_str(), F_OK) == 0)
100  return name;
101 
102  name = directory + file + dot_ext;
103  if (access(name.c_str(), F_OK) == 0)
104  return name;
105 
106  name = dir + file + dot_ext;
107  if (access(name.c_str(), F_OK) == 0)
108  return name;
109 
110  name = dir + ext;
111  if (access(name.c_str(), F_OK) == 0)
112  return name;
113 
114  return "";
115 }
116 
117 // Given a pathname to a datafile, take that pathname apart and look for an
118 // ancillary file that describes a group of datafiles of which this datafile
119 // is a member. Assume that groups follow a simple naming convention where
120 // files use either leading or trailing digits and a common basename to name
121 // group members. For example, 00stuff.hdf, 01stuff.hdf, 02stuff.hdf, ..., is
122 // a group and is has `stuff' as its basename.
123 
137 string
138 Ancillary::find_group_ancillary_file( const string &name, const string &ext )
139 {
140  // Given /usr/local/data/stuff.01.nc
141  // pathname = /usr/local/data, filename = stuff.01.nc and
142  // rootname = stuff.01
143  string::size_type slash = name.find_last_of('/');
144  string dirname = name.substr(0, slash);
145  string filename = name.substr(slash + 1);
146  string rootname = filename.substr(0, filename.find_last_of('.'));
147 
148  // Instead of using regexs, scan the filename for leading and then
149  // trailing digits.
150  string::iterator rootname_iter = rootname.begin();
151  string::iterator rootname_end_iter = rootname.end();
152  if (isdigit(*rootname_iter)) {
153  while (rootname_iter != rootname_end_iter
154  && isdigit(*++rootname_iter))
155  ;
156 
157  // We want: new_name = dirname + "/" + <base> + ext but without
158  // creating a bunch of temp objects.
159  string new_name = dirname;
160  new_name.append("/");
161  new_name.append(rootname_iter, rootname_end_iter);
162  new_name.append(ext);
163  DBG(cerr << "New Name (iter): " << new_name << endl);
164  if (access(new_name.c_str(), F_OK) == 0) {
165  return new_name;
166  }
167  }
168 
169  string::reverse_iterator rootname_riter = rootname.rbegin();
170  string::reverse_iterator rootname_end_riter = rootname.rend();
171  if (isdigit(*rootname_riter)) {
172  while (rootname_riter != rootname_end_riter
173  && isdigit(*++rootname_riter))
174  ;
175  string new_name = dirname;
176  new_name.append("/");
177  // I used reverse iters to scan rootname backwards. To avoid
178  // reversing the fragment between end_riter and riter, pass append
179  // regular iters obtained using reverse_iterator::base(). See Meyers
180  // p. 123. 1/22/2002 jhrg
181  new_name.append(rootname_end_riter.base(), rootname_riter.base());
182  new_name.append(ext);
183  DBG(cerr << "New Name (riter): " << new_name << endl);
184  if (access(new_name.c_str(), F_OK) == 0) {
185  return new_name;
186  }
187  }
188 
189  // If we're here either the file does not begin with leading digits or a
190  // template made by removing those digits was not found.
191 
192  return "";
193 }
194 
195 void
196 Ancillary::read_ancillary_das( DAS &das,
197  const string &pathname,
198  const string &dir,
199  const string &file )
200 {
201  string name = find_ancillary_file( pathname, "das", dir, file ) ;
202 
203  DBG(cerr << "In Ancillary::read_ancillary_dds: name:" << name << endl);
204 
205  FILE *in = fopen( name.c_str(), "r" ) ;
206  if( in ) {
207  das.parse( in ) ;
208  (void)fclose( in ) ;
209 #if 0
210  int res = fclose( in ) ;
211  if( res )
212  DBG(cerr << "Ancillary::read_ancillary_das - Failed to close file " << (void *)in << endl) ;
213 #endif
214  }
215 }
216 
217 void
218 Ancillary::read_ancillary_dds( DDS &dds,
219  const string &pathname,
220  const string &dir,
221  const string &file )
222 {
223  string name = find_ancillary_file( pathname, "dds", dir, file ) ;
224 
225  DBG(cerr << "In Ancillary::read_ancillary_dds: name:" << name << endl);
226 
227  FILE *in = fopen( name.c_str(), "r" ) ;
228  if( in ) {
229  dds.parse( in ) ;
230  (void)fclose( in ) ;
231 #if 0
232  int res = fclose( in ) ;
233  if( res )
234  DBG(cerr << "Ancillary::read_ancillary_das - Failed to close file " << (void *)in << endl) ;
235 #endif
236  }
237 }
238 
239 } // namespace libdap
240 
static string find_group_ancillary_file(const string &pathname, const string &ext)
Definition: Ancillary.cc:138
static string find_ancillary_file(const string &pathname, const string &ext, const string &dir, const string &file)
Find a file with ancillary data.
Definition: Ancillary.cc:69
top level DAP object to house generic methods
Definition: AISConnect.cc:30
void parse(string fname)
Parse a DDS from a file with the given d_name.
Definition: DDS.cc:942
virtual void parse(string fname)
Reads a DAS from the named file.
Definition: DAS.cc:232
Hold attribute data for a DAP2 dataset.
Definition: DAS.h:121