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