libdap Updated for version 3.20.11
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
22namespace libdap {
23
68string
69Ancillary::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
137string
138Ancillary::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
195void
196Ancillary::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 }
210}
211
212void
213Ancillary::read_ancillary_dds( DDS &dds,
214 const string &pathname,
215 const string &dir,
216 const string &file )
217{
218 string name = find_ancillary_file( pathname, "dds", dir, file ) ;
219
220 DBG(cerr << "In Ancillary::read_ancillary_dds: name:" << name << endl);
221
222 FILE *in = fopen( name.c_str(), "r" ) ;
223 if( in ) {
224 dds.parse( in ) ;
225 (void)fclose( in ) ;
226 }
227}
228
229} // namespace libdap
230
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
Hold attribute data for a DAP2 dataset.
Definition: DAS.h:122
virtual void parse(string fname)
Reads a DAS from the named file.
Definition: DAS.cc:230
top level DAP object to house generic methods
Definition: AlarmHandler.h:36