From e15a1e03df03fc51bdc9db611e5fe21eb5747127 Mon Sep 17 00:00:00 2001 From: James Gallagher Date: Thu, 10 May 2018 10:26:32 -0600 Subject: [PATCH] Comments, some loose ends with the print code in dmrpp_module I made the DMR++ namespace and namespace prefix static class fields of DmrppCommon. This way we can change the default prefix using a parameter in the module's conf file. --- doxy.conf.in | 4 ++- modules/dmrpp_module/DMRpp.cc | 36 +++++++++++++++++++++++--- modules/dmrpp_module/DMRpp.h | 5 +++- modules/dmrpp_module/DmrppArray.cc | 39 +++++++++++++++++++++-------- modules/dmrpp_module/DmrppArray.h | 7 ++++++ modules/dmrpp_module/DmrppCommon.cc | 15 ++++++++++- modules/dmrpp_module/DmrppCommon.h | 4 ++- modules/hdf5_handler | 2 +- 8 files changed, 93 insertions(+), 19 deletions(-) diff --git a/doxy.conf.in b/doxy.conf.in index 55670b1d7a..3578a2b8a9 100644 --- a/doxy.conf.in +++ b/doxy.conf.in @@ -833,9 +833,9 @@ EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = */old/* \ */not-used/* \ +*/unused/* \ */tests/* \ */unit-tests/* \ -*/modules/* \ */templates/* \ */apache/* \ */bin/* \ @@ -848,6 +848,8 @@ Test*.cc \ Test*.h \ *Test.cc \ *T.cc + +# This was excluded. jhrg 5/10/18 */modules/* \ # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the diff --git a/modules/dmrpp_module/DMRpp.cc b/modules/dmrpp_module/DMRpp.cc index eec6040204..55a8a1f37a 100644 --- a/modules/dmrpp_module/DMRpp.cc +++ b/modules/dmrpp_module/DMRpp.cc @@ -34,8 +34,37 @@ using namespace libdap; namespace dmrpp { +#if 0 +/** + * @brief The DMR++ namespace. + */ const string dmrpp_namespace = "http://xml.opendap.org/dap/dmrpp/1.0.0#"; - +#endif + + +/** + * @brief Print the DMR++ response + * + * This is a clone of DMR::print_dap4() modified to include the DMR++ namespace + * and to print the DMR++ XML which is the standard DMR XML with the addition of + * new elements that include information about the 'chunks' that hold data values. + + * It uses a static field defined in DmrppCommon to control whether the + * chunk information should be printed. The third argument \arg print_chunks + * will set this static class member to true or false, which controls the + * output of the chunk information. This method resets the field to its previous + * value on exit. + * + * @param xml Writer the XML to this instance of XMLWriter + * @param constrained Should the DMR++ be constrained, in the same sense that the + * DMR::print_dap4() method can print a constrained DMR. False by default. + * @param print_chunks Print the chunks? This parameter sets the DmrppCommon::d_print_chunks + * static field. That field is used by other methods in the Dmrpp classes to + * control if they print the chunk information. True by default. + * + * @see DmrppArray::print_dap4() + * @see DmrppCommon::print_dmrpp() + */ void DMRpp::print_dmrpp(XMLWriter &xml, bool constrained, bool print_chunks) { bool pc_initial_value = DmrppCommon::d_print_chunks; @@ -51,8 +80,9 @@ void DMRpp::print_dmrpp(XMLWriter &xml, bool constrained, bool print_chunks) // The dmrpp namespace if (DmrppCommon::d_print_chunks) - if (xmlTextWriterWriteAttribute(xml.get_writer(), (const xmlChar*) "xmlns:dmrpp", - (const xmlChar*) dmrpp_namespace.c_str()) < 0) + if (xmlTextWriterWriteAttribute(xml.get_writer(), + (const xmlChar*)string("xmlns:").append(DmrppCommon::d_ns_prefix).c_str(), + (const xmlChar*)DmrppCommon::d_dmrpp_ns.c_str()) < 0) throw InternalErr(__FILE__, __LINE__, "Could not write attribute for xmlns:dmrpp"); if (!request_xml_base().empty()) { diff --git a/modules/dmrpp_module/DMRpp.h b/modules/dmrpp_module/DMRpp.h index 05dc11327b..9ba19e9e37 100644 --- a/modules/dmrpp_module/DMRpp.h +++ b/modules/dmrpp_module/DMRpp.h @@ -33,12 +33,15 @@ class XMLWriter; namespace dmrpp { +/** + * @brief Provide a way to print the DMR++ response + */ class DMRpp : public libdap::DMR { public: DMRpp() { } virtual ~DMRpp() { } - virtual void print_dmrpp(libdap::XMLWriter &xml, bool constrained = false, bool print_chunks = false); + virtual void print_dmrpp(libdap::XMLWriter &xml, bool constrained = false, bool print_chunks = true); }; } /* namespace dmrpp */ diff --git a/modules/dmrpp_module/DmrppArray.cc b/modules/dmrpp_module/DmrppArray.cc index 403f779a1b..9a046696b0 100644 --- a/modules/dmrpp_module/DmrppArray.cc +++ b/modules/dmrpp_module/DmrppArray.cc @@ -46,6 +46,7 @@ #include "DmrppArray.h" #include "DmrppRequestHandler.h" +// Used with BESDEBUG static const string dmrpp_3 = "dmrpp:3"; using namespace libdap; @@ -213,7 +214,7 @@ void DmrppArray::insert_constrained_contiguous(Dim_iter dimIter, unsigned long * subsetAddress.pop_back(); // Copy data block from start_index to stop_index - // FIXME Replace this loop with a call to std::memcpy() + // TODO Replace this loop with a call to std::memcpy() for (unsigned long sourceIndex = start_index; sourceIndex <= stop_index; sourceIndex++) { unsigned long target_byte = *target_index * bytesPerElt; unsigned long source_byte = sourceIndex * bytesPerElt; @@ -484,10 +485,6 @@ void DmrppArray::read_chunks_serial() * When \arg dim is the array's rank, `target_element_address` will * have a value for all but the rightmost dimension. * - * @todo Save the target element address with the chunk for use in the - * insert code. It might be useful to compute the last (rightmost) - * component of the `target_element_address.` - * * @param dim Starting with 0, compute values for this dimension of the array * @param target_element_address Initially empty, this becomes the location * in the array where data should be written. @@ -831,11 +828,31 @@ class PrintD4MapXMLWriter: public unary_function { }; ///@} +/** + * @brief Shadow libdap::Array::print_dap4() - optionally prints DMR++ chunk information + * + * This version of libdap::BaseType::print_dap4() will print information about + * HDF5 chunks when the value of the static class filed dmrpp::DmrppCommon::d_print_chunks + * is true. The method DMRpp::print_dmrpp() will set the _d_pprint_chunks_ field to + * true causing this method to include the _chunks_ elements in its output. When + * the field's value is false, this method prints the same output as libdap::Array. + * + * @note There are, no doubt, better ways to do this than using what is essentially a + * global flag; one way is to synchronize access to a DMR C++ object and a DOM + * tree for the same DMR document. The chunk information can be read from the DMR and + * inserted into the DOM tree, which then printed. If the + * approach I took here becomes an issue (i.e., if we have to fix problems in libdap and + * here because of code duplication), we should probably recode this and the related + * methods to use the 'DOM tree approach.' + * + * @param xml Write the XML to this instance of XMLWriter + * @param constrained True if the response should be constrained. False by default + * + * @see DmrppCommon::print_dmrpp() + * @see DMRpp::print_dmrpp() + */ void DmrppArray::print_dap4(XMLWriter &xml, bool constrained /*false*/) { -#if USE_LIBDAP_print_dap4 - Array::print_dap4(writer, constrained); -#else if (constrained && !send_p()) return; if (xmlTextWriterStartElement(xml.get_writer(), (const xmlChar*) var()->type_name().c_str()) < 0) @@ -870,13 +887,13 @@ void DmrppArray::print_dap4(XMLWriter &xml, bool constrained /*false*/) for_each(maps()->map_begin(), maps()->map_end(), PrintD4MapXMLWriter(xml)); - // Only print the chunks info if there. + // Only print the chunks info if there. This is the code added to libdap::Array::print_dap4(). + // jhrg 5/10/18 if (DmrppCommon::d_print_chunks && get_immutable_chunks().size() > 0) - print_chunks_element(xml, "dmrpp"); + print_chunks_element(xml, DmrppCommon::d_ns_prefix); if (xmlTextWriterEndElement(xml.get_writer()) < 0) throw InternalErr(__FILE__, __LINE__, "Could not end " + type_name() + " element"); -#endif } void DmrppArray::dump(ostream & strm) const diff --git a/modules/dmrpp_module/DmrppArray.h b/modules/dmrpp_module/DmrppArray.h index 8d46abb8ed..470d76dd5a 100644 --- a/modules/dmrpp_module/DmrppArray.h +++ b/modules/dmrpp_module/DmrppArray.h @@ -31,6 +31,13 @@ #include "DmrppCommon.h" +// The 'read_serial()' method is more closely related to the original code +// used to read data when the DMR++ handler was initial developed for NASA. +// I modified that code for a while when we built the prototype version of +// the handler, but then morphed that into a version that would support parallel +// access. Defining this symbol will include the old code in the handler, +// although the DmrppArray::read() method will still have to be hacked to +// use it. jhrg 5/10/18 #undef USE_READ_SERIAL namespace libdap { diff --git a/modules/dmrpp_module/DmrppCommon.cc b/modules/dmrpp_module/DmrppCommon.cc index ef85025cea..99cd829b09 100644 --- a/modules/dmrpp_module/DmrppCommon.cc +++ b/modules/dmrpp_module/DmrppCommon.cc @@ -46,6 +46,8 @@ using namespace libdap; namespace dmrpp { bool DmrppCommon::d_print_chunks = false; +string DmrppCommon::d_dmrpp_ns = "http://xml.opendap.org/dap/dmrpp/1.0.0#"; +string DmrppCommon::d_ns_prefix = "dmrpp"; /** * @brief Set the dimension sizes for a chunk @@ -236,6 +238,16 @@ DmrppCommon::print_chunks_element(XMLWriter &xml, const string &name_space) } } +/** + * @brief Print the DMR++ response for the Scalar types + * + * @note See DmrppArray::print_dap4() for a discussion about the design of + * this, and related, method. + * + * @param xml Write the XML to this instance of XMLWriter + * @param constrained If true, print the constrained DMR. False by default. + * @see DmrppArray::print_dap4() + */ void DmrppCommon::print_dap4(XMLWriter &xml, bool constrained /*false*/) { BaseType &bt = dynamic_cast(*this); @@ -255,8 +267,9 @@ void DmrppCommon::print_dap4(XMLWriter &xml, bool constrained /*false*/) if (!bt.is_dap4() && bt.get_attr_table().get_size() > 0) bt.get_attr_table().print_xml_writer(xml); + // This is the code added to libdap::BaseType::print_dap4(). jhrg 5/10/18 if (DmrppCommon::d_print_chunks && get_immutable_chunks().size() > 0) - print_chunks_element(xml, "dmrpp"); + print_chunks_element(xml, DmrppCommon::d_ns_prefix); if (xmlTextWriterEndElement(xml.get_writer()) < 0) throw InternalErr(__FILE__, __LINE__, "Could not end " + bt.type_name() + " element"); diff --git a/modules/dmrpp_module/DmrppCommon.h b/modules/dmrpp_module/DmrppCommon.h index 6afd2176df..15d6a9cc6d 100644 --- a/modules/dmrpp_module/DmrppCommon.h +++ b/modules/dmrpp_module/DmrppCommon.h @@ -86,7 +86,9 @@ class DmrppCommon { virtual char *read_atomic(const std::string &name); public: - static bool d_print_chunks; ///< if true, print_dap4() prints chunk elements + static bool d_print_chunks; ///< if true, print_dap4() prints chunk elements + static string d_dmrpp_ns; ///< The DMR++ XML namespace + static string d_ns_prefix; ///< The XML namespace prefix to use DmrppCommon() : d_deflate(false), d_shuffle(false) { diff --git a/modules/hdf5_handler b/modules/hdf5_handler index cb14294250..6f7a7cdacf 160000 --- a/modules/hdf5_handler +++ b/modules/hdf5_handler @@ -1 +1 @@ -Subproject commit cb14294250b613793f75222ef52681eb3fc6ef6e +Subproject commit 6f7a7cdacf39d5584977a57a0aade8d181660772