bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
d4_tools.cc
1// d4_tools.cc
2
3// This file is part of BES Netcdf File Out Module
4
5// Copyright (c) 2004,2005 University Corporation for Atmospheric Research
6// Author: Patrick West <pwest@ucar.edu> and Jose Garcia <jgarcia@ucar.edu>
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11// version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21//
22// You can contact University Corporation for Atmospheric Research at
23// 3080 Center Green Drive, Boulder, CO 80301
24
25// (c) COPYRIGHT University Corporation for Atmospheric Research 2004-2005
26// Please read the full copyright statement in the file COPYRIGHT_UCAR.
27//
28// Authors:
29// slloyd Samuel Lloyd <slloyd@opendap.org>
30
31#include <libdap/D4Group.h>
32#include <libdap/D4Attributes.h>
33#include <libdap/Array.h>
34#include <libdap/Structure.h>
35
36#include <exception>
37
38#include <BESInternalError.h>
39#include <vector>
40
41#include "d4_tools.h"
42#include "FONcAttributes.h"
43#include "FONcTransmitter.h"
44#include "history_utils.h"
45
46#include "DMR.h"
47#include "DDS.h"
48
49using namespace libdap;
50using namespace std;
51
52#define prolog std::string("d4_tools::").append(__func__).append("() - ")
53
54bool d4_tools::has_dap4_types(D4Attribute *attr)
55{
56 bool has_d4_attr = false;
57 switch(attr->type()){
58 case attr_int8_c:
59 case attr_int64_c:
60 case attr_uint64_c:
61 has_d4_attr=true;
62 break;
63 case attr_container_c:
64 has_d4_attr = has_dap4_types(attr->attributes());
65 break;
66 default:
67 break;
68 }
69 return has_d4_attr;
70}
71
72bool d4_tools::has_dap4_types(const D4Attributes *attrs)
73{
74 bool has_d4_attr = false;
75 for (auto attr: attrs->attributes()) {
76 if(has_dap4_types(attr))
77 has_d4_attr |= has_dap4_types(attr);
78 }
79 return has_d4_attr;
80}
81
82bool d4_tools::is_dap4_projected(libdap::BaseType *var, vector<BaseType *> &inv) {
83
84 switch(var->type()){
85 case libdap::dods_int8_c:
86 case libdap::dods_int64_c:
87 case libdap::dods_uint64_c:
88 inv.push_back(var);
89 return true;
90 case libdap::dods_array_c: {
91 auto *a = dynamic_cast<Array*>(var);
92 if (d4_tools::is_dap4_projected(a->var(), inv)) {
93 inv.pop_back(); // removing array template type ...
94 inv.push_back(var); // ... and add array type into inventory
95 return true;
96 }
97 break;
98 }
99 case libdap::dods_structure_c:
100 case libdap::dods_grid_c:
101 case libdap::dods_sequence_c: {
102 auto *svar = dynamic_cast<Constructor*>(var);
103 bool is_dap4 = false;
104 for (auto bvar = svar->var_begin(), evar = svar->var_end(); bvar != evar; ++bvar){
105
106 if (d4_tools::is_dap4_projected(*bvar, inv)){
107 is_dap4 = true;
108 }
109 }
110 if(is_dap4) return true;
111 }
112 default:
113 break;
114 }
115 // Projected variable might not be DAP4, but what about the attributes?
116 if(has_dap4_types(var->attributes())){
117 // It has DAP4 Attributes so that variable is a de-facto dap4 variable.
118 inv.push_back(var);
119 return true;
120 }
121 return false;
122}
123
124#if 1
125bool d4_tools::is_dap4_projected(DDS *_dds, vector<BaseType *> &projected_dap4_variable_inventory) {
126 bool has_dap4_var = false;
127 for (auto btp = _dds->var_begin(), ve = _dds->var_end(); btp != ve; ++btp) {
128
129 BaseType *var = *btp;
130 if(var->send_p() && is_dap4_projected(var, projected_dap4_variable_inventory)){
131 has_dap4_var = true;
132 }
133 }
134 return has_dap4_var;
135}
136#endif
137
138#if 1
139bool d4_tools::is_dap4_projected(DMR *_dmr, vector<BaseType *> &projected_dap4_variable_inventory) {
140
141 bool has_dap4_var = false;
142
143 has_dap4_var = is_dap4_projected( _dmr->root(), projected_dap4_variable_inventory);
144
145 return has_dap4_var;
146}
147#endif
148
149#if 1
150bool d4_tools::is_dap4_projected(D4Group *group, vector<BaseType *> &projected_dap4_variable_inventory){
151 bool has_dap4_var = false;
152 // variables in the group
153
154 // check all variables in the root group
155 for (auto btp = group->var_begin(), ve = group->var_end(); btp != ve; ++btp) {
156 BaseType *var = *btp;
157
158 if(var->send_p() && var->type() != libdap::dods_group_c){ //dods_group_c <- d4Groups
159 if (is_dap4_projected(var, projected_dap4_variable_inventory)) {
160 has_dap4_var = true;
161 }
162 }
163 else if (var->send_p() && var->type() == libdap::dods_group_c) {
164 try {
165 D4Group *d4g = dynamic_cast<D4Group *>(var);
166 if (is_dap4_projected(d4g, projected_dap4_variable_inventory)) {
167 has_dap4_var = true;
168 }
169 }
170 catch (const exception &e){
171 throw BESInternalError("Exception: " + string(e.what()), __FILE__, __LINE__);
172 }
173 }
174 }
175
176 //check if group has any subgroups and check them for dap4 projected variables
177 for (auto gb = group->grp_begin(), ge = group->grp_end(); gb != ge; ++gb){
178 try {
179 D4Group *d4g = *gb;
180 if (is_dap4_projected(d4g, projected_dap4_variable_inventory)) {
181 has_dap4_var = true;
182 }
183 }
184 catch (const exception &e){
185 throw BESInternalError("Exception: " + string(e.what()), __FILE__, __LINE__);
186 }
187
188 }
189 return has_dap4_var;
190}
191#endif
exception thrown if internal error encountered