41 static char rcsid[] not_used = {
"$Id$"};
61 #include <Structure.h>
64 #include <Ancillary.h>
74 #include "../usage/usage.h"
77 using namespace dap_usage;
81 #define pclose _pclose
87 #define RETURN_TYPE void
89 #define RETURN_TYPE int
103 static Regex *dim_ptr = 0 ;
105 static pthread_once_t dim_once_control = PTHREAD_ONCE_INIT;
112 static Regex dim(
".*_dim_[0-9]*", 1);
117 name_in_kill_file(
const string &name)
120 pthread_once(&dim_once_control, init_dim_regex);
128 bool ret = dim_ptr->match(name.c_str(), name.length()) != -1;
132 static Regex *global_ptr = 0 ;
134 static pthread_once_t global_once_control = PTHREAD_ONCE_INIT;
141 static Regex global(
"(.*global.*)|(.*dods.*)", 1);
142 global_ptr = &global;
146 name_is_global(
string &name)
149 pthread_once(&global_once_control, init_global_regex);
156 return global_ptr->match(name.c_str(), name.length()) != -1;
165 write_global_attributes(ostringstream &oss, AttrTable *attr,
166 const string prefix =
"")
169 AttrTable::Attr_iter a;
170 for (a = attr->attr_begin(); a != attr->attr_end(); a++) {
171 if (attr->is_container(a))
172 write_global_attributes(oss, attr->get_attr_table(a),
173 (prefix ==
"") ? attr->get_name(a)
174 : prefix +
string(
".") + attr->get_name(a));
176 oss <<
"\n<tr><td align=right valign=top><b>";
178 oss << prefix <<
"." << attr->get_name(a);
180 oss << attr->get_name(a);
181 oss <<
"</b>:</td>\n";
183 int num_attr = attr->get_attr_num(a) - 1;
184 oss <<
"<td align=left>";
185 for (
int i = 0; i < num_attr; ++i)
186 oss << attr->get_attr(a, i) <<
", ";
187 oss << attr->get_attr(a, num_attr) <<
"<br></td></tr>\n";
194 write_attributes(ostringstream &oss, AttrTable *attr,
const string prefix =
"")
197 AttrTable::Attr_iter a;
198 for (a = attr->attr_begin(); a != attr->attr_end(); a++) {
199 if (attr->is_container(a))
200 write_attributes(oss, attr->get_attr_table(a),
201 (prefix ==
"") ? attr->get_name(a)
202 : prefix +
string(
".") + attr->get_name(a));
205 oss << prefix <<
"." << attr->get_name(a);
207 oss << attr->get_name(a);
210 int num_attr = attr->get_attr_num(a) - 1 ;
211 for (
int i = 0; i < num_attr; ++i)
212 oss << attr->get_attr(a, i) <<
", ";
213 oss << attr->get_attr(a, num_attr) <<
"<br>\n";
232 build_global_attributes(DAS &das, DDS &)
237 ga <<
"<h3>Dataset Information</h3>\n<center>\n<table>\n";
239 for (AttrTable::Attr_iter p = das.var_begin(); p != das.var_end(); p++) {
240 string name = das.get_name(p);
246 if (!name_in_kill_file(name) )
248 if( name_is_global(name)) {
249 AttrTable *attr = das.get_table(p);
251 write_global_attributes(ga, attr,
"");
256 ga <<
"</table>\n</center><p>\n";
265 fancy_typename(BaseType *v)
272 return "16 bit Integer";
274 return "16 bit Unsigned integer";
276 return "32 bit Integer";
278 return "32 bit Unsigned integer";
280 return "32 bit Real";
282 return "64 bit Real";
289 Array *a = (Array *)v;
290 type <<
"Array of " << fancy_typename(a->var()) <<
"s ";
291 for (Array::Dim_iter p = a->dim_begin(); p != a->dim_end(); p++) {
292 type <<
"[" << a->dimension_name(p) <<
" = 0.."
293 << a->dimension_size(p,
false)-1 <<
"]";
298 case dods_structure_c:
300 case dods_sequence_c:
310 write_variable(BaseType *btp, DAS &das, ostringstream &vs)
312 vs <<
"<td align=right valign=top><b>" << btp->name()
314 <<
"<td align=left valign=top>" << fancy_typename(btp)
317 AttrTable *attr = das.get_table(btp->name());
319 write_attributes(vs, attr,
"");
321 switch (btp->type()) {
335 case dods_structure_c: {
337 Structure *sp =
dynamic_cast<Structure *
>(btp);
338 for (Constructor::Vars_iter p = sp->var_begin(); p != sp->var_end(); p++)
341 write_variable((*p), das, vs);
348 case dods_sequence_c: {
350 Sequence *sp =
dynamic_cast<Sequence *
>(btp);
351 for (Constructor::Vars_iter p = sp->var_begin(); p != sp->var_end(); p++)
354 write_variable((*p), das, vs);
363 Grid *gp =
dynamic_cast<Grid *
>(btp);
364 write_variable(gp->array_var(), das, vs);
366 for (p = gp->map_begin(); p != gp->map_end(); p++) {
368 write_variable((*p), das, vs);
376 throw InternalErr(__FILE__, __LINE__,
"Unknown type");
389 build_variable_summaries(DAS &das, DDS &dds)
392 vs <<
"<h3>Variables in this Dataset</h3>\n<center>\n<table>\n";
395 for (DDS::Vars_iter p = dds.var_begin(); p != dds.var_end(); p++) {
397 write_variable((*p), das, vs);
401 vs <<
"</table>\n</center><p>\n";
407 html_header( ostream &strm )
409 strm <<
"HTTP/1.0 200 OK\r\n" ;
410 strm <<
"XDODS-Server: " << PACKAGE_VERSION <<
"\r\n" ;
411 strm <<
"XDAP: " << DAP_PROTOCOL_VERSION <<
"\r\n" ;
412 strm <<
"Content-type: text/html\r\n" ;
413 strm <<
"Content-Description: dods_description\r\n" ;
436 write_usage_response(ostream &strm, DDS &dds, DAS &das,
437 const string &dataset_name,
438 const string &server_name,
439 bool httpheader)
throw(
Error)
443 string user_html = get_user_supplied_docs(dataset_name, server_name);
445 string global_attrs = build_global_attributes(das, dds);
447 string variable_sum = build_variable_summaries(das, dds);
454 strm <<
"<html><head><title>Dataset Information</title></head>"
455 <<
"\n" <<
"<body>" <<
"\n" ;
457 if (global_attrs.length())
459 strm << global_attrs.c_str() <<
"\n" <<
"<hr>" <<
"\n" ;
462 strm << variable_sum.c_str() <<
"\n" ;
466 strm << user_html.c_str() <<
"\n" ;
468 strm <<
"</body>\n</html>\n" ;
494 get_user_supplied_docs(
string name,
string cgi)
498 ifstream ifs((cgi +
".html").c_str());
502 ifs.getline(tmp, 255);
515 ifs.open((name +
".html").c_str());
519 string new_name = Ancillary::find_group_ancillary_file(name,
".html");
521 ifs.open(new_name.c_str());
526 ifs.getline(tmp, 255);