bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
DMZ.h
1
2// -*- mode: c++; c-basic-offset:4 -*-
3
4// This file is part of the BES
5
6// Copyright (c) 2021 OPeNDAP, Inc.
7// Author: James Gallagher <jgallagher@opendap.org>
8//
9// This library is free software; you can redistribute it and/or
10// modify it under the terms of the GNU Lesser General Public
11// License as published by the Free Software Foundation; either
12// version 2.1 of the License, or (at your option) any later version.
13//
14// This library is distributed in the hope that it will be useful,
15// but WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17// Lesser General Public License for more details.
18//
19// You should have received a copy of the GNU Lesser General Public
20// License along with this library; if not, write to the Free Software
21// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22//
23// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25#ifndef h_dmz_h
26#define h_dmz_h 1
27
28#include <string>
29#include <vector>
30#include <set>
31#include <queue>
32#include <memory>
33
34#define PUGIXML_NO_XPATH
35#define PUGIXML_HEADER_ONLY
36#include <pugixml.hpp>
37
38#include <libdap/Type.h>
39#include <DmrppStructure.h>
40#include <DmrppArray.h>
41
42namespace libdap {
43class DMR;
44class BaseType;
45class Array;
46class D4Group;
47class D4Attributes;
48class Constructor;
49}
50
51namespace http {
52class url;
53}
54
55namespace dmrpp {
56
57using shape = std::vector<unsigned long long>;
58
59class Chunk;
60class DmrppCommon;
61
74class DMZ {
75
76private:
77 pugi::xml_document d_xml_doc;
78 std::shared_ptr<http::url> d_dataset_elem_href;
79
80 // Controls if teh parser will drop variables that have been flagged
81 // with a dmrpp:chunks/@fillValue attribute value of "unsupported-*"
82 // This is set from TheBESKeys in the DMZ's constructor.
83 static bool d_elide_unsupported;
84
86 static const std::set<std::string> variable_elements;
87
88 static void load_config_from_keys();
89 void process_dataset(libdap::DMR *dmr, const pugi::xml_node &xml_root);
90 static pugi::xml_node get_variable_xml_node(libdap::BaseType *btp);
91 void add_mblock_index(const pugi::xml_node &chunk,std::queue<std::vector<std::pair<unsigned long long, unsigned long long>>>& mb_index_queue,
92 std::vector<std::pair<unsigned long long, unsigned long long >>&) const;
93 void process_chunk(dmrpp::DmrppCommon *dc, const pugi::xml_node &chunk) const;
94 void process_block(dmrpp::DmrppCommon *dc, const pugi::xml_node &chunk, unsigned int block_count) const;
95 void process_multi_blocks_chunk(dmrpp::DmrppCommon *dc, const pugi::xml_node &chunk, std::queue<std::vector<std::pair<unsigned long long, unsigned long long>>>& mb_index_queue) const;
96 bool process_chunks(libdap::BaseType *btp, const pugi::xml_node &chunks) const;
97
98 static void process_fill_value_chunks(libdap::BaseType *btp, const std::set<shape> &chunk_map, const shape &chunk_shape,
99 const shape &array_shape, unsigned long long chunk_size, unsigned int struct_size);
100
101 static bool is_simple_dap_structure_scalar_array(libdap::BaseType *btp, std::vector<std::pair<libdap::Type,int>> &structure_type_element);
102 static bool is_simple_dap_structure_internal(const libdap::Structure *ds, std::vector<std::pair<libdap::Type,int>> &structure_type_element);
103
104 static std::vector<unsigned long long int> get_array_dims(libdap::Array *array);
105 static size_t logical_chunks(const std::vector<unsigned long long> &array_dim_sizes, const dmrpp::DmrppCommon *dc);
106 static std::set< std::vector<unsigned long long> > get_chunk_map(const std::vector<std::shared_ptr<Chunk>> &chunks);
107
108 static void process_compact(libdap::BaseType *btp, const pugi::xml_node &compact);
109 static void process_compact_subset(DmrppArray *da, std::vector<u_int8_t>& decoded);
110 static void process_missing_data(libdap::BaseType *btp, const pugi::xml_node &missing_data);
111 static void handle_subset(dmrpp::DmrppArray *da, libdap::Array::Dim_iter dim_iter, unsigned long & subset_index, std::vector<unsigned long long> & subset_pos,
112 std::vector<unsigned char>& subset_buf, std::vector<unsigned char>& whole_buf);
113 static size_t INDEX_nD_TO_1D (const std::vector <unsigned long long > &dims, const std::vector < unsigned long long> &pos) ;
114
115 static void process_special_structure_data(libdap::BaseType *btp, const pugi::xml_node &special_structure_data);
116 static void process_special_structure_data_internal(DmrppStructure * dmrpp_s, std::vector<u_int8_t> &values , size_t total_value_size, size_t & values_offset);
117 static bool supported_special_structure_type(libdap::BaseType *btp);
118 static bool supported_special_structure_type_internal(libdap::Constructor *var_ctor);
119 static void process_vlsa(libdap::BaseType *btp, const pugi::xml_node &vlsa_element);
120
121 static pugi::xml_node get_variable_xml_node_helper(const pugi::xml_node &var_node, std::stack<libdap::BaseType*> &bt);
122 static void build_basetype_chain(libdap::BaseType *btp, std::stack<libdap::BaseType*> &bt);
123
124 static void process_group(libdap::DMR *dmr, libdap::D4Group *parent, const pugi::xml_node &var_node);
125 static void process_dimension(libdap::D4Group *grp, const pugi::xml_node &dimension_node);
126 static void process_variable(libdap::DMR *dmr, libdap::D4Group *grp, libdap::Constructor *parent, const pugi::xml_node &var_node);
127 static void process_dim(libdap::DMR *dmr, libdap::D4Group *grp, libdap::Array *array, const pugi::xml_node &dim_node);
128 static void process_map(libdap::DMR *dmr, libdap::D4Group *grp, libdap::Array *array, const pugi::xml_node &map_node);
129 static libdap::BaseType *build_variable(libdap::DMR *dmr, libdap::D4Group *group, libdap::Type t, const pugi::xml_node &var_node);
130 static libdap::BaseType *add_scalar_variable(libdap::DMR *dmr, libdap::D4Group *group, libdap::Constructor *parent, libdap::Type t, const pugi::xml_node &var_node);
131 static libdap::BaseType *add_array_variable(libdap::DMR *dmr, libdap::D4Group *grp, libdap::Constructor *parent, libdap::Type t, const pugi::xml_node &var_node);
132 static void process_attribute(libdap::D4Attributes *attributes, const pugi::xml_node &dap_attr_node);
133
134 static void process_cds_node(dmrpp::DmrppCommon *dc, const pugi::xml_node &chunks);
135
136 void load_attributes(libdap::BaseType *btp, pugi::xml_node var_node) const;
137
138 friend class DMZTest;
139
140public:
141
143 DMZ() = default;
144
145 explicit DMZ(const std::string &file_name);
146
147 virtual ~DMZ() = default;
148
149 // This is not virtual because we call it from a ctor
150 void parse_xml_doc(const std::string &filename);
151
152 void parse_xml_string(const std::string &contents);
153
154 virtual void build_thin_dmr(libdap::DMR *dmr);
155
156 virtual bool set_up_all_direct_io_flags_phase_1(libdap::DMR *dmr);
157 virtual bool set_up_direct_io_flag_phase_1(libdap::D4Group *group);
158 virtual bool set_up_direct_io_flag_phase_1(libdap::BaseType *btp);
159
160 virtual void set_up_all_direct_io_flags_phase_2(libdap::DMR *dmr);
161 virtual void set_up_direct_io_flag_phase_2(libdap::D4Group *group);
162 virtual void set_up_direct_io_flag_phase_2(libdap::BaseType *btp);
163
164
165 virtual void load_attributes(libdap::BaseType *btp);
166 virtual void load_attributes(libdap::Constructor *constructor);
167 virtual void load_attributes(libdap::D4Group *group);
168
169 virtual void load_chunks(libdap::BaseType *btp);
170
171 virtual void load_all_attributes(libdap::DMR *dmr);
172};
173
174} // namespace dmrpp
175
176#endif // h_dmz_h
177
DMZ()=default
Build a DMZ without simultaneously parsing an XML document.
virtual void load_chunks(libdap::BaseType *btp)
Load the chunk information into a variable.
Definition DMZ.cc:2230
void parse_xml_doc(const std::string &filename)
Build the DOM tree for a DMR++ XML document.
Definition DMZ.cc:185
virtual void build_thin_dmr(libdap::DMR *dmr)
populate the DMR instance as a 'thin DMR'
Definition DMZ.cc:773
void parse_xml_string(const std::string &contents)
Build a DOM tree for a DMR++ using content from a string.
Definition DMZ.cc:290
Extend libdap::Array so that a handler can read data using a DMR++ file.
Definition DmrppArray.h:77
Size and offset information of data included in DMR++ files.
Definition DmrppCommon.h:97
Parse a URL into the protocol, host, path and query parts.
Definition url_impl.h:44
utility class for the HTTP catalog module
Definition TheBESKeys.h:51