<commit_before>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of ff_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 2.1 of the License, or (at your
// option) any later version.
//
// This software is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// FFRequestHandler.cc

#include "config_ff.h"

#include <iostream>
#include <string>
#include <sstream>
#include <exception>

#include <DDS.h>
#include <DMR.h>
#include <D4BaseTypeFactory.h>
#include <Ancillary.h>
#include <Error.h>
#include <InternalErr.h>
#include <mime_util.h>
#include <escaping.h>

#include <BESResponseHandler.h>
#include <BESResponseNames.h>
#include <BESDapNames.h>
#include <BESDASResponse.h>
#include <BESDDSResponse.h>
#include <BESDataDDSResponse.h>
#include <BESDMRResponse.h>
#include <BESVersionInfo.h>

#include <BESDapError.h>
#include <BESInternalFatalError.h>
#include <BESDataNames.h>
#include <TheBESKeys.h>
#include <BESServiceRegistry.h>
#include <BESUtil.h>
#include <BESDebug.h>
#include <BESContextManager.h>

#include "FFRequestHandler.h"
//#include "D4FFTypeFactory.h"
#include "ff_ce_functions.h"
#include "util_ff.h"

using namespace std;

#define FF_NAME "ff"

long BufPtr = 0; // cache pointer
long BufSiz = 0; // Cache size
char *BufVal = NULL; // cache buffer

extern void ff_read_descriptors(DDS & dds, const string & filename);
extern void ff_get_attributes(DAS & das, string filename);

bool FFRequestHandler::d_RSS_format_support = false;
string FFRequestHandler::d_RSS_format_files = "";

FFRequestHandler::FFRequestHandler(const string &name) :
        BESRequestHandler(name)
{
    add_handler(DAS_RESPONSE, FFRequestHandler::ff_build_das);
    add_handler(DDS_RESPONSE, FFRequestHandler::ff_build_dds);
    add_handler(DATA_RESPONSE, FFRequestHandler::ff_build_data);

    add_handler(DMR_RESPONSE, FFRequestHandler::ff_build_dmr);
    add_handler(DAP4DATA_RESPONSE, FFRequestHandler::ff_build_dmr);

    add_handler(HELP_RESPONSE, FFRequestHandler::ff_build_help);
    add_handler(VERS_RESPONSE, FFRequestHandler::ff_build_version);

    ff_register_functions();

    bool key_found = false;
    string doset;
    TheBESKeys::TheKeys()->get_value("FF.RSSFormatSupport", doset, key_found);
    if (key_found) {
        doset = BESUtil::lowercase(doset);
        if (doset == "true" || doset == "yes")
            FFRequestHandler::d_RSS_format_support = true;
        else
            FFRequestHandler::d_RSS_format_support = false;
    }
    else
        FFRequestHandler::d_RSS_format_support = false;

    key_found = false;
    string path;
    TheBESKeys::TheKeys()->get_value("FF.RSSFormatFiles", path, key_found);
    if (key_found)
        FFRequestHandler::d_RSS_format_files = path;
    else
        FFRequestHandler::d_RSS_format_files = "";

    BESDEBUG("ff", "d_RSS_format_support: " << d_RSS_format_support << endl);
    BESDEBUG("ff", "d_RSS_format_files: " << d_RSS_format_files << endl);
}

FFRequestHandler::~FFRequestHandler()
{
}

bool FFRequestHandler::ff_build_das(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
    if (!bdas)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    try {
        bdas->set_container(dhi.container->get_symbolic_name());
        DAS *das = bdas->get_das();

        string accessed = dhi.container->access();
        ff_get_attributes(*das, accessed);

        string name;
        if (FFRequestHandler::get_RSS_format_support()) {
            name = find_ancillary_rss_das(accessed);
        }
        else {
            name = Ancillary::find_ancillary_file(accessed, "das", "", "");
        }

        struct stat st;
        if (!name.empty() && (stat(name.c_str(), &st) == 0)) {
            das->parse(name);
        }

        bdas->clear_container();
    } catch (InternalErr & e) {
        BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (Error & e) {
        BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (...) {
        BESInternalFatalError ex("unknown exception caught building Freeform DAS", __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_dds(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
    if (!bdds)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    try {
        bdds->set_container(dhi.container->get_symbolic_name());
        DDS *dds = bdds->get_dds();
        string accessed = dhi.container->access();
        dds->filename(accessed);

        BESDEBUG("ff", "FFRequestHandler::ff_build_dds, accessed: " << accessed << endl);

        ff_read_descriptors(*dds, accessed);

        BESDEBUG("ff", "FFRequestHandler::ff_build_dds, reading attributes" << endl);

        DAS *das = new DAS;
        BESDASResponse bdas(das);
        bdas.set_container(dhi.container->get_symbolic_name());
        ff_get_attributes(*das, accessed);
        Ancillary::read_ancillary_das(*das, accessed);

        BESDEBUG("ff", "FFRequestHandler::ff_build_dds, transferring attributes" << endl);

        dds->transfer_attributes(das);

        bdds->set_constraint(dhi);

        bdds->clear_container();

    } catch (InternalErr & e) {
        BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (Error & e) {
        BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (...) {
        BESInternalFatalError ex("unknown exception caught building Freeform DDS", __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_data(BESDataHandlerInterface & dhi)
{
    BufPtr = 0; // cache pointer
    BufSiz = 0; // Cache size
    BufVal = NULL; // cache buffer

    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
    if (!bdds)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    try {
        bdds->set_container(dhi.container->get_symbolic_name());
        DataDDS *dds = bdds->get_dds();
        string accessed = dhi.container->access();
        dds->filename(accessed);
        ff_read_descriptors(*dds, accessed);
        Ancillary::read_ancillary_dds(*dds, accessed);

        DAS *das = new DAS;
        BESDASResponse bdas(das);
        bdas.set_container(dhi.container->get_symbolic_name());
        ff_get_attributes(*das, accessed);
        Ancillary::read_ancillary_das(*das, accessed);

        dds->transfer_attributes(das);

        bdds->set_constraint(dhi);

        bdds->clear_container();
    } catch (InternalErr & e) {
        BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (Error & e) {
        BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (...) {
        BESInternalFatalError ex("unknown exception caught building Freeform DataDDS", __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

/**
 * Build the DMR object.
 *
 * This is used for both the DAP4 DMR and Data responses. This version of the
 * method uses the DMR's 'DDS constructor'.
 *
 * @param dhi
 * @return True on success or throw an exception on error.
 */
bool FFRequestHandler::ff_build_dmr(BESDataHandlerInterface &dhi)
{
    BufPtr = 0; // cache pointer
    BufSiz = 0; // Cache size
    BufVal = NULL; // cache buffer

	// Because this code does not yet know how to build a DMR directly, use
	// the DMR ctor that builds a DMR using a 'full DDS' (a DDS with attributes).
	// First step, build the 'full DDS'
	string data_path = dhi.container->access();

	BaseTypeFactory factory;
	DDS dds(&factory, name_path(data_path), "3.2");
	dds.filename(data_path);

	try {
		ff_read_descriptors(dds, data_path);
		// ancillary DDS objects never took off - this does nothing. jhrg 8/12/14
		// Ancillary::read_ancillary_dds(*dds, data_path);

		DAS das;
		ff_get_attributes(das, data_path);
		Ancillary::read_ancillary_das(das, data_path);
		dds.transfer_attributes(&das);
	}
	catch (InternalErr &e) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch (Error &e) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch (...) {
		throw BESDapError("Caught unknown error build FF DMR response", true, unknown_error, __FILE__, __LINE__);
	}

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	DMR *dmr = bdmr.get_dmr();
	dmr->set_factory(new D4BaseTypeFactory);
	dmr->build_using_dds(dds);

	// Instead of fiddling with the internal storage of the DHI object,
	// (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
	// methods to set the constraints. But, why? Maybe setting data[]
	// directly is better? jhrg 8/14/14
	bdmr.set_dap4_constraint(dhi);
	bdmr.set_dap4_function(dhi);

	// What about async and store_result? See BESDapTransmit::send_dap4_data()

	return true;
}

bool FFRequestHandler::ff_build_help(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESInfo *info = dynamic_cast<BESInfo *>(response);
    if (!info)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    map < string, string > attrs;
    attrs["name"] = MODULE_NAME ;
    attrs["version"] = MODULE_VERSION ;
#if 0
    attrs["name"] = PACKAGE_NAME;
    attrs["version"] = PACKAGE_VERSION;
#endif
    list < string > services;
    BESServiceRegistry::TheRegistry()->services_handled(FF_NAME, services);
    if (services.size() > 0) {
        string handles = BESUtil::implode(services, ',');
        attrs["handles"] = handles;
    }
    info->begin_tag("module", &attrs);
    info->end_tag("module");

    return true;
}

bool FFRequestHandler::ff_build_version(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
    if (!info)
        throw BESInternalError("cast error", __FILE__, __LINE__);

#if 0
    info->add_module(PACKAGE_NAME, PACKAGE_VERSION);
#endif
    info->add_module(MODULE_NAME, MODULE_VERSION);

    return true;
}
<commit_msg>Fixed DataDDS include and libdap namespace after repairing the BESDataDDSResponse header<commit_after>// -*- mode: c++; c-basic-offset:4 -*-

// This file is part of ff_handler, a data handler for the OPeNDAP data
// server.

// Copyright (c) 2002,2003 OPeNDAP, Inc.
// Author: James Gallagher <jgallagher@opendap.org>
//
// This is free software; you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 2.1 of the License, or (at your
// option) any later version.
//
// This software is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
// License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.

// FFRequestHandler.cc

#include "config_ff.h"

#include <iostream>
#include <string>
#include <sstream>
#include <exception>

#include <DDS.h>
#include <DataDDS.h>
#include <DMR.h>
#include <D4BaseTypeFactory.h>
#include <Ancillary.h>
#include <Error.h>
#include <InternalErr.h>
#include <mime_util.h>
#include <escaping.h>

#include <BESResponseHandler.h>
#include <BESResponseNames.h>
#include <BESDapNames.h>
#include <BESDASResponse.h>
#include <BESDDSResponse.h>
#include <BESDataDDSResponse.h>
#include <BESDMRResponse.h>
#include <BESVersionInfo.h>

#include <BESDapError.h>
#include <BESInternalFatalError.h>
#include <BESDataNames.h>
#include <TheBESKeys.h>
#include <BESServiceRegistry.h>
#include <BESUtil.h>
#include <BESDebug.h>
#include <BESContextManager.h>

#include "FFRequestHandler.h"
//#include "D4FFTypeFactory.h"
#include "ff_ce_functions.h"
#include "util_ff.h"

using namespace libdap;
using namespace std;

#define FF_NAME "ff"

long BufPtr = 0; // cache pointer
long BufSiz = 0; // Cache size
char *BufVal = NULL; // cache buffer

extern void ff_read_descriptors(DDS & dds, const string & filename);
extern void ff_get_attributes(DAS & das, string filename);

bool FFRequestHandler::d_RSS_format_support = false;
string FFRequestHandler::d_RSS_format_files = "";

FFRequestHandler::FFRequestHandler(const string &name) :
        BESRequestHandler(name)
{
    add_handler(DAS_RESPONSE, FFRequestHandler::ff_build_das);
    add_handler(DDS_RESPONSE, FFRequestHandler::ff_build_dds);
    add_handler(DATA_RESPONSE, FFRequestHandler::ff_build_data);

    add_handler(DMR_RESPONSE, FFRequestHandler::ff_build_dmr);
    add_handler(DAP4DATA_RESPONSE, FFRequestHandler::ff_build_dmr);

    add_handler(HELP_RESPONSE, FFRequestHandler::ff_build_help);
    add_handler(VERS_RESPONSE, FFRequestHandler::ff_build_version);

    ff_register_functions();

    bool key_found = false;
    string doset;
    TheBESKeys::TheKeys()->get_value("FF.RSSFormatSupport", doset, key_found);
    if (key_found) {
        doset = BESUtil::lowercase(doset);
        if (doset == "true" || doset == "yes")
            FFRequestHandler::d_RSS_format_support = true;
        else
            FFRequestHandler::d_RSS_format_support = false;
    }
    else
        FFRequestHandler::d_RSS_format_support = false;

    key_found = false;
    string path;
    TheBESKeys::TheKeys()->get_value("FF.RSSFormatFiles", path, key_found);
    if (key_found)
        FFRequestHandler::d_RSS_format_files = path;
    else
        FFRequestHandler::d_RSS_format_files = "";

    BESDEBUG("ff", "d_RSS_format_support: " << d_RSS_format_support << endl);
    BESDEBUG("ff", "d_RSS_format_files: " << d_RSS_format_files << endl);
}

FFRequestHandler::~FFRequestHandler()
{
}

bool FFRequestHandler::ff_build_das(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESDASResponse *bdas = dynamic_cast<BESDASResponse *>(response);
    if (!bdas)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    try {
        bdas->set_container(dhi.container->get_symbolic_name());
        DAS *das = bdas->get_das();

        string accessed = dhi.container->access();
        ff_get_attributes(*das, accessed);

        string name;
        if (FFRequestHandler::get_RSS_format_support()) {
            name = find_ancillary_rss_das(accessed);
        }
        else {
            name = Ancillary::find_ancillary_file(accessed, "das", "", "");
        }

        struct stat st;
        if (!name.empty() && (stat(name.c_str(), &st) == 0)) {
            das->parse(name);
        }

        bdas->clear_container();
    } catch (InternalErr & e) {
        BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (Error & e) {
        BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (...) {
        BESInternalFatalError ex("unknown exception caught building Freeform DAS", __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_dds(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESDDSResponse *bdds = dynamic_cast<BESDDSResponse *>(response);
    if (!bdds)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    try {
        bdds->set_container(dhi.container->get_symbolic_name());
        DDS *dds = bdds->get_dds();
        string accessed = dhi.container->access();
        dds->filename(accessed);

        BESDEBUG("ff", "FFRequestHandler::ff_build_dds, accessed: " << accessed << endl);

        ff_read_descriptors(*dds, accessed);

        BESDEBUG("ff", "FFRequestHandler::ff_build_dds, reading attributes" << endl);

        DAS *das = new DAS;
        BESDASResponse bdas(das);
        bdas.set_container(dhi.container->get_symbolic_name());
        ff_get_attributes(*das, accessed);
        Ancillary::read_ancillary_das(*das, accessed);

        BESDEBUG("ff", "FFRequestHandler::ff_build_dds, transferring attributes" << endl);

        dds->transfer_attributes(das);

        bdds->set_constraint(dhi);

        bdds->clear_container();

    } catch (InternalErr & e) {
        BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (Error & e) {
        BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (...) {
        BESInternalFatalError ex("unknown exception caught building Freeform DDS", __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

bool FFRequestHandler::ff_build_data(BESDataHandlerInterface & dhi)
{
    BufPtr = 0; // cache pointer
    BufSiz = 0; // Cache size
    BufVal = NULL; // cache buffer

    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESDataDDSResponse *bdds = dynamic_cast<BESDataDDSResponse *>(response);
    if (!bdds)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    try {
        bdds->set_container(dhi.container->get_symbolic_name());
        DataDDS *dds = bdds->get_dds();
        string accessed = dhi.container->access();
        dds->filename(accessed);
        ff_read_descriptors(*dds, accessed);
        Ancillary::read_ancillary_dds(*dds, accessed);

        DAS *das = new DAS;
        BESDASResponse bdas(das);
        bdas.set_container(dhi.container->get_symbolic_name());
        ff_get_attributes(*das, accessed);
        Ancillary::read_ancillary_das(*das, accessed);

        dds->transfer_attributes(das);

        bdds->set_constraint(dhi);

        bdds->clear_container();
    } catch (InternalErr & e) {
        BESDapError ex(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (Error & e) {
        BESDapError ex(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
        throw ex;
    } catch (...) {
        BESInternalFatalError ex("unknown exception caught building Freeform DataDDS", __FILE__, __LINE__);
        throw ex;
    }

    return true;
}

/**
 * Build the DMR object.
 *
 * This is used for both the DAP4 DMR and Data responses. This version of the
 * method uses the DMR's 'DDS constructor'.
 *
 * @param dhi
 * @return True on success or throw an exception on error.
 */
bool FFRequestHandler::ff_build_dmr(BESDataHandlerInterface &dhi)
{
    BufPtr = 0; // cache pointer
    BufSiz = 0; // Cache size
    BufVal = NULL; // cache buffer

	// Because this code does not yet know how to build a DMR directly, use
	// the DMR ctor that builds a DMR using a 'full DDS' (a DDS with attributes).
	// First step, build the 'full DDS'
	string data_path = dhi.container->access();

	BaseTypeFactory factory;
	DDS dds(&factory, name_path(data_path), "3.2");
	dds.filename(data_path);

	try {
		ff_read_descriptors(dds, data_path);
		// ancillary DDS objects never took off - this does nothing. jhrg 8/12/14
		// Ancillary::read_ancillary_dds(*dds, data_path);

		DAS das;
		ff_get_attributes(das, data_path);
		Ancillary::read_ancillary_das(das, data_path);
		dds.transfer_attributes(&das);
	}
	catch (InternalErr &e) {
		throw BESDapError(e.get_error_message(), true, e.get_error_code(), __FILE__, __LINE__);
	}
	catch (Error &e) {
		throw BESDapError(e.get_error_message(), false, e.get_error_code(), __FILE__, __LINE__);
	}
	catch (...) {
		throw BESDapError("Caught unknown error build FF DMR response", true, unknown_error, __FILE__, __LINE__);
	}

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	BESResponseObject *response = dhi.response_handler->get_response_object();
	BESDMRResponse &bdmr = dynamic_cast<BESDMRResponse &>(*response);

	// Extract the DMR Response object - this holds the DMR used by the
	// other parts of the framework.
	DMR *dmr = bdmr.get_dmr();
	dmr->set_factory(new D4BaseTypeFactory);
	dmr->build_using_dds(dds);

	// Instead of fiddling with the internal storage of the DHI object,
	// (by setting dhi.data[DAP4_CONSTRAINT], etc., directly) use these
	// methods to set the constraints. But, why? Maybe setting data[]
	// directly is better? jhrg 8/14/14
	bdmr.set_dap4_constraint(dhi);
	bdmr.set_dap4_function(dhi);

	// What about async and store_result? See BESDapTransmit::send_dap4_data()

	return true;
}

bool FFRequestHandler::ff_build_help(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESInfo *info = dynamic_cast<BESInfo *>(response);
    if (!info)
        throw BESInternalError("cast error", __FILE__, __LINE__);

    map < string, string > attrs;
    attrs["name"] = MODULE_NAME ;
    attrs["version"] = MODULE_VERSION ;
#if 0
    attrs["name"] = PACKAGE_NAME;
    attrs["version"] = PACKAGE_VERSION;
#endif
    list < string > services;
    BESServiceRegistry::TheRegistry()->services_handled(FF_NAME, services);
    if (services.size() > 0) {
        string handles = BESUtil::implode(services, ',');
        attrs["handles"] = handles;
    }
    info->begin_tag("module", &attrs);
    info->end_tag("module");

    return true;
}

bool FFRequestHandler::ff_build_version(BESDataHandlerInterface & dhi)
{
    BESResponseObject *response = dhi.response_handler->get_response_object();
    BESVersionInfo *info = dynamic_cast<BESVersionInfo *>(response);
    if (!info)
        throw BESInternalError("cast error", __FILE__, __LINE__);

#if 0
    info->add_module(PACKAGE_NAME, PACKAGE_VERSION);
#endif
    info->add_module(MODULE_NAME, MODULE_VERSION);

    return true;
}
<|endoftext|>


<commit_before>// Author: Enrico Guiraud, Danilo Piparo CERN  03/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "RConfigure.h"      // R__USE_IMT
#include "ROOT/RMakeUnique.hxx" // std::make_unique
#include "ROOT/TDFNodes.hxx" // ColumnName2ColumnTypeName -> TCustomColumnBase, FindUnknownColumns -> TLoopManager
#include "ROOT/TDFUtils.hxx"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TClassRef.h"
#include "TFriendElement.h"
#include "TROOT.h" // IsImplicitMTEnabled, GetImplicitMTPoolSize

#include <stdexcept>
#include <string>
class TTree;
using namespace ROOT::Detail::TDF;
using namespace ROOT::Experimental::TDF;

namespace ROOT {
namespace Internal {
namespace TDF {

TIgnoreErrorLevelRAII::TIgnoreErrorLevelRAII(int errorIgnoreLevel)
{
   gErrorIgnoreLevel = errorIgnoreLevel;
}
TIgnoreErrorLevelRAII::~TIgnoreErrorLevelRAII()
{
   gErrorIgnoreLevel = fCurIgnoreErrorLevel;
}

/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
/// column created by Define.
std::string
ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
{
   if (ds && ds->HasColumn(colName)) {
      return ds->GetTypeName(colName);
   }

   TBranch *branch = nullptr;
   if (tree)
      branch = tree->GetBranch(colName.c_str());
   if (!branch && !tmpBranch) {
      throw std::runtime_error("Column \"" + colName + "\" is not in a file and has not been defined.");
   }
   if (branch) {
      // this must be a real TTree branch
      static const TClassRef tbranchelRef("TBranchElement");
      if (branch->InheritsFrom(tbranchelRef)) {
         return static_cast<TBranchElement *>(branch)->GetClassName();
      } else { // Try the fundamental type
         std::string_view title(branch->GetTitle());
         char typeCode = title.back();
         std::string type;
         if (typeCode == 'B')
            type = "char";
         else if (typeCode == 'b')
            type = "unsigned char";
         else if (typeCode == 'I')
            type = "int";
         else if (typeCode == 'i')
            type = "unsigned int";
         else if (typeCode == 'S')
            type = "short";
         else if (typeCode == 's')
            type = "unsigned short";
         else if (typeCode == 'D')
            type = "double";
         else if (typeCode == 'F')
            type = "float";
         else if (typeCode == 'L')
            type = "Long64_t";
         else if (typeCode == 'l')
            type = "ULong64_t";
         else if (typeCode == 'O')
            type = "bool";
         if (title[title.size() - 3] == ']') {
            // title has the form "varname[size]/X", i.e. it refers to an array (doesn't matter if size is fixed or not)
            // TDataFrame reads it as an array_view
            // TODO change array_view to span when available
            return "std::array_view<" + type + ">";
         } else {
            return type;
         }
      }
   } else {
      // this must be a temporary branch
      const auto &type_id = tmpBranch->GetTypeId();
      if (auto c = TClass::GetClass(type_id)) {
         return c->GetName();
      } else if (type_id == typeid(char))
         return "char";
      else if (type_id == typeid(unsigned char))
         return "unsigned char";
      else if (type_id == typeid(int))
         return "int";
      else if (type_id == typeid(unsigned int))
         return "unsigned int";
      else if (type_id == typeid(short))
         return "short";
      else if (type_id == typeid(unsigned short))
         return "unsigned short";
      else if (type_id == typeid(long))
         return "long";
      else if (type_id == typeid(unsigned long))
         return "unsigned long";
      else if (type_id == typeid(double))
         return "double";
      else if (type_id == typeid(float))
         return "float";
      else if (type_id == typeid(Long64_t))
         return "Long64_t";
      else if (type_id == typeid(ULong64_t))
         return "ULong64_t";
      else if (type_id == typeid(bool))
         return "bool";
      else {
         std::string msg("Cannot deduce type of temporary column ");
         msg += colName.c_str();
         msg += ". The typename is ";
         msg += tmpBranch->GetTypeId().name();
         msg += ".";
         throw std::runtime_error(msg);
      }
   }
   // we never reach here
}

const char *ToConstCharPtr(const char *s)
{
   return s;
}

const char *ToConstCharPtr(const std::string &s)
{
   return s.c_str();
}

unsigned int GetNSlots()
{
   unsigned int nSlots = 1;
#ifdef R__USE_IMT
   if (ROOT::IsImplicitMTEnabled())
      nSlots = ROOT::GetImplicitMTPoolSize();
#endif // R__USE_IMT
   return nSlots;
}

void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols,
                       const ColumnNames_t &dataSourceColumns)
{
   const std::string definedColStr(definedCol);
   if (treePtr != nullptr) {
      // check if definedCol is already present in TTree
      const auto branch = treePtr->GetBranch(definedColStr.c_str());
      if (branch != nullptr) {
         const auto msg = "branch \"" + definedColStr + "\" already present in TTree";
         throw std::runtime_error(msg);
      }
   }
   // check if definedCol has already been `Define`d in the functional graph
   if (std::find(customCols.begin(), customCols.end(), definedCol) != customCols.end()) {
      const auto msg = "Redefinition of column \"" + definedColStr + "\"";
      throw std::runtime_error(msg);
   }
   // check if definedCol is already present in the DataSource (but has not yet been `Define`d)
   if (!dataSourceColumns.empty()) {
      if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end()) {
         const auto msg = "Redefinition of column \"" + definedColStr + "\" already present in the data-source";
         throw std::runtime_error(msg);
      }
   }
}

void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
{
   if (nTemplateParams != nColumnNames) {
      std::string err_msg = "The number of template parameters specified for the snapshot is ";
      err_msg += std::to_string(nTemplateParams);
      err_msg += " while ";
      err_msg += std::to_string(nColumnNames);
      err_msg += " columns have been specified.";
      throw std::runtime_error(err_msg);
   }
}

/// Choose between local column names or default column names, throw in case of errors.
const ColumnNames_t
SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
{
   if (names.empty()) {
      // use default column names
      if (defaultNames.size() < nRequiredNames)
         throw std::runtime_error(
            std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
            " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
      // return first nRequiredNames default column names
      return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
   } else {
      // use column names provided by the user to this particular transformation/action
      if (names.size() != nRequiredNames) {
         auto msg = std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
                    " required but " + std::to_string(names.size()) + (names.size() == 1 ? " was" : " were") +
                    " provided:";
         for (const auto &name : names)
            msg += " \"" + name + "\",";
         msg.back() = '.';
         throw std::runtime_error(msg);
      }
      return names;
   }
}

ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, TTree *tree, const ColumnNames_t &definedCols,
                                 const ColumnNames_t &dataSourceColumns)
{
   ColumnNames_t unknownColumns;
   const auto friends = tree ? tree->GetListOfFriends() : static_cast<TList*>(nullptr);
   for (auto &column : requiredCols) {
      const auto isTreeBranch = (tree != nullptr && tree->GetBranch(column.c_str()) != nullptr);
      if (isTreeBranch)
         continue;
      const auto isCustomColumn = std::find(definedCols.begin(), definedCols.end(), column) != definedCols.end();
      if (isCustomColumn)
         continue;
      const auto isDataSourceColumn =
         std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
      if (isDataSourceColumn)
         continue;
      if (friends) {
         bool isFriendBranch = false;
         for (auto friendTree : *friends) {
            const auto friendBranch = static_cast<TFriendElement *>(friendTree)->GetTree()->GetBranch(column.c_str());
            if (friendBranch != nullptr) {
               isFriendBranch = true;
               break;
            }
         }
         if (isFriendBranch)
            continue;
      }

      unknownColumns.emplace_back(column);
   }
   return unknownColumns;
}

bool IsInternalColumn(std::string_view colName)
{
   return colName.find("__TDF_") == 0;
}

} // end NS TDF
} // end NS Internal
} // end NS ROOT
<commit_msg>Revert "[TO FIXUP] Make clang-format happy"<commit_after>// Author: Enrico Guiraud, Danilo Piparo CERN  03/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "RConfigure.h"      // R__USE_IMT
#include "ROOT/RMakeUnique.hxx" // std::make_unique
#include "ROOT/TDFNodes.hxx" // ColumnName2ColumnTypeName -> TCustomColumnBase, FindUnknownColumns -> TLoopManager
#include "ROOT/TDFUtils.hxx"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TClassRef.h"
#include "TFriendElement.h"
#include "TROOT.h" // IsImplicitMTEnabled, GetImplicitMTPoolSize

#include <stdexcept>
#include <string>
class TTree;
using namespace ROOT::Detail::TDF;
using namespace ROOT::Experimental::TDF;

namespace ROOT {
namespace Internal {
namespace TDF {

TIgnoreErrorLevelRAII::TIgnoreErrorLevelRAII(int errorIgnoreLevel)
{
   gErrorIgnoreLevel = errorIgnoreLevel;
}
TIgnoreErrorLevelRAII::~TIgnoreErrorLevelRAII()
{
   gErrorIgnoreLevel = fCurIgnoreErrorLevel;
}

/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
/// column created by Define.
std::string
ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
{
   if (ds && ds->HasColumn(colName)) {
      return ds->GetTypeName(colName);
   }

   TBranch *branch = nullptr;
   if (tree)
      branch = tree->GetBranch(colName.c_str());
   if (!branch && !tmpBranch) {
      throw std::runtime_error("Column \"" + colName + "\" is not in a file and has not been defined.");
   }
   if (branch) {
      // this must be a real TTree branch
      static const TClassRef tbranchelRef("TBranchElement");
      if (branch->InheritsFrom(tbranchelRef)) {
         return static_cast<TBranchElement *>(branch)->GetClassName();
      } else { // Try the fundamental type
         std::string_view title(branch->GetTitle());
         char typeCode = title.back();
         std::string type;
         if (typeCode == 'B')
            type = "char";
         else if (typeCode == 'b')
            type = "unsigned char";
         else if (typeCode == 'I')
            type = "int";
         else if (typeCode == 'i')
            type = "unsigned int";
         else if (typeCode == 'S')
            type = "short";
         else if (typeCode == 's')
            type = "unsigned short";
         else if (typeCode == 'D')
            type = "double";
         else if (typeCode == 'F')
            type = "float";
         else if (typeCode == 'L')
            type = "Long64_t";
         else if (typeCode == 'l')
            type = "ULong64_t";
         else if (typeCode == 'O')
            type = "bool";
         if (title[title.size() - 3] == ']') {
            // title has the form "varname[size]/X", i.e. it refers to an array (doesn't matter if size is fixed or not)
            // TDataFrame reads it as an array_view
            // TODO change array_view to span when available
            return "std::array_view<" + type + ">";
         } else {
            return type;
         }
      }
   } else {
      // this must be a temporary branch
      const auto &type_id = tmpBranch->GetTypeId();
      if (auto c = TClass::GetClass(type_id)) {
         return c->GetName();
      } else if (type_id == typeid(char))
         return "char";
      else if (type_id == typeid(unsigned char))
         return "unsigned char";
      else if (type_id == typeid(int))
         return "int";
      else if (type_id == typeid(unsigned int))
         return "unsigned int";
      else if (type_id == typeid(short))
         return "short";
      else if (type_id == typeid(unsigned short))
         return "unsigned short";
      else if (type_id == typeid(long))
         return "long";
      else if (type_id == typeid(unsigned long))
         return "unsigned long";
      else if (type_id == typeid(double))
         return "double";
      else if (type_id == typeid(float))
         return "float";
      else if (type_id == typeid(Long64_t))
         return "Long64_t";
      else if (type_id == typeid(ULong64_t))
         return "ULong64_t";
      else if (type_id == typeid(bool))
         return "bool";
      else {
         std::string msg("Cannot deduce type of temporary column ");
         msg += colName.c_str();
         msg += ". The typename is ";
         msg += tmpBranch->GetTypeId().name();
         msg += ".";
         throw std::runtime_error(msg);
      }
   }
   // we never reach here
}

const char *ToConstCharPtr(const char *s)
{
   return s;
}

const char *ToConstCharPtr(const std::string &s)
{
   return s.c_str();
}

unsigned int GetNSlots()
{
   unsigned int nSlots = 1;
#ifdef R__USE_IMT
   if (ROOT::IsImplicitMTEnabled())
      nSlots = ROOT::GetImplicitMTPoolSize();
#endif // R__USE_IMT
   return nSlots;
}

void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols,
                       const ColumnNames_t &dataSourceColumns)
{
   const std::string definedColStr(definedCol);
   if (treePtr != nullptr) {
      // check if definedCol is already present in TTree
      const auto branch = treePtr->GetBranch(definedColStr.c_str());
      if (branch != nullptr) {
         const auto msg = "branch \"" + definedColStr + "\" already present in TTree";
         throw std::runtime_error(msg);
      }
   }
   // check if definedCol has already been `Define`d in the functional graph
   if (std::find(customCols.begin(), customCols.end(), definedCol) != customCols.end()) {
      const auto msg = "Redefinition of column \"" + definedColStr + "\"";
      throw std::runtime_error(msg);
   }
   // check if definedCol is already present in the DataSource (but has not yet been `Define`d)
   if (!dataSourceColumns.empty()) {
      if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end()) {
         const auto msg = "Redefinition of column \"" + definedColStr + "\" already present in the data-source";
         throw std::runtime_error(msg);
      }
   }
}

void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
{
   if (nTemplateParams != nColumnNames) {
      std::string err_msg = "The number of template parameters specified for the snapshot is ";
      err_msg += std::to_string(nTemplateParams);
      err_msg += " while ";
      err_msg += std::to_string(nColumnNames);
      err_msg += " columns have been specified.";
      throw std::runtime_error(err_msg);
   }
}

/// Choose between local column names or default column names, throw in case of errors.
const ColumnNames_t
SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
{
   if (names.empty()) {
      // use default column names
      if (defaultNames.size() < nRequiredNames)
         throw std::runtime_error(
            std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
            " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
      // return first nRequiredNames default column names
      return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
   } else {
      // use column names provided by the user to this particular transformation/action
      if (names.size() != nRequiredNames) {
         auto msg = std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
                    " required but " + std::to_string(names.size()) + (names.size() == 1 ? " was" : " were") +
                    " provided:";
         for (const auto &name : names)
            msg += " \"" + name + "\",";
         msg.back() = '.';
         throw std::runtime_error(msg);
      }
      return names;
   }
}

ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, TTree *tree, const ColumnNames_t &definedCols,
                                 const ColumnNames_t &dataSourceColumns)
{
   ColumnNames_t unknownColumns;
   const auto friends = tree ? tree->GetListOfFriends() : static_cast<TList*>(nullptr);
   for (auto &column : requiredCols) {
      const auto isTreeBranch = (tree != nullptr && tree->GetBranch(column.c_str()) != nullptr);
      if (isTreeBranch)
         continue;
      const auto isCustomColumn = std::find(definedCols.begin(), definedCols.end(), column) != definedCols.end();
      if (isCustomColumn)
         continue;
      const auto isDataSourceColumn =
         std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
      if (isDataSourceColumn)
         continue;
      if (friends) {
         bool isFriendBranch = false;
         for (auto friendTree : *friends) {
            const auto friendBranch = static_cast<TFriendElement*>(friendTree)->GetTree()->GetBranch(column.c_str());
            if (friendBranch != nullptr) {
               isFriendBranch = true;
               break;
            }
         }
         if (isFriendBranch)
            continue;
      }

      unknownColumns.emplace_back(column);
   }
   return unknownColumns;
}

bool IsInternalColumn(std::string_view colName)
{
   return colName.find("__TDF_") == 0;
}

} // end NS TDF
} // end NS Internal
} // end NS ROOT
<|endoftext|>


<commit_before>// Author: Enrico Guiraud, Danilo Piparo CERN  03/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "RConfigure.h"      // R__USE_IMT
#include "ROOT/TDFNodes.hxx" // ColumnName2ColumnTypeName -> TCustomColumnBase, FindUnknownColumns -> TLoopManager
#include "ROOT/TDFUtils.hxx"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TClassRef.h"
#include "TFriendElement.h"
#include "TROOT.h" // IsImplicitMTEnabled, GetImplicitMTPoolSize

#include <stdexcept>
#include <string>
class TTree;
using namespace ROOT::Detail::TDF;
using namespace ROOT::Experimental::TDF;

namespace ROOT {
namespace Internal {
namespace TDF {

TIgnoreErrorLevelRAII::TIgnoreErrorLevelRAII(int errorIgnoreLevel)
{
   gErrorIgnoreLevel = errorIgnoreLevel;
}
TIgnoreErrorLevelRAII::~TIgnoreErrorLevelRAII()
{
   gErrorIgnoreLevel = fCurIgnoreErrorLevel;
}

/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
/// column created by Define. Returns an empty string if type name deduction fails.
std::string
ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
{
   if (ds && ds->HasColumn(colName)) {
      return ds->GetTypeName(colName);
   }

   TBranch *branch = nullptr;
   if (tree)
      branch = tree->GetBranch(colName.c_str());
   if (!branch && !tmpBranch) {
      throw std::runtime_error("Column \"" + colName + "\" is not in a file and has not been defined.");
   }
   if (branch) {
      // this must be a real TTree branch
      static const TClassRef tbranchelRef("TBranchElement");
      if (branch->InheritsFrom(tbranchelRef)) {
         return static_cast<TBranchElement *>(branch)->GetClassName();
      } else { // Try the fundamental type
         std::string_view title(branch->GetTitle());
         char typeCode = title.back();
         std::string type;
         if (typeCode == 'B')
            type = "char";
         else if (typeCode == 'b')
            type = "unsigned char";
         else if (typeCode == 'I')
            type = "int";
         else if (typeCode == 'i')
            type = "unsigned int";
         else if (typeCode == 'S')
            type = "short";
         else if (typeCode == 's')
            type = "unsigned short";
         else if (typeCode == 'D')
            type = "double";
         else if (typeCode == 'F')
            type = "float";
         else if (typeCode == 'n')
            type = "Float_t";
         else if (typeCode == 'L')
            type = "Long64_t";
         else if (typeCode == 'l')
            type = "ULong64_t";
         else if (typeCode == 'O')
            type = "bool";
         if (title[title.size() - 3] == ']') {
            // title has the form "varname[size]/X", i.e. it refers to an array (doesn't matter if size is fixed or not)
            // TDataFrame reads it as a TArrayBranch
            return "ROOT::Experimental::TDF::TArrayBranch<" + type + ">";
         } else {
            return type;
         }
      }
   } else {
      // this must be a temporary branch
      const auto &type_id = tmpBranch->GetTypeId();
      if (auto c = TClass::GetClass(type_id)) {
         return c->GetName();
      } else if (type_id == typeid(char))
         return "char";
      else if (type_id == typeid(unsigned char))
         return "unsigned char";
      else if (type_id == typeid(int))
         return "int";
      else if (type_id == typeid(unsigned int))
         return "unsigned int";
      else if (type_id == typeid(short))
         return "short";
      else if (type_id == typeid(unsigned short))
         return "unsigned short";
      else if (type_id == typeid(long))
         return "long";
      else if (type_id == typeid(unsigned long))
         return "unsigned long";
      else if (type_id == typeid(double))
         return "double";
      else if (type_id == typeid(float))
         return "float";
      else if (type_id == typeid(Long64_t))
         return "Long64_t";
      else if (type_id == typeid(ULong64_t))
         return "ULong64_t";
      else if (type_id == typeid(bool))
         return "bool";
      else {
         std::string msg("Cannot deduce type of temporary column ");
         msg += colName.c_str();
         msg += ". The typename is ";
         msg += tmpBranch->GetTypeId().name();
         msg += ".";
         throw std::runtime_error(msg);
      }
   }
   // we never reach here
}

const char *ToConstCharPtr(const char *s)
{
   return s;
}

const char *ToConstCharPtr(const std::string &s)
{
   return s.c_str();
}

unsigned int GetNSlots()
{
   unsigned int nSlots = 1;
#ifdef R__USE_IMT
   if (ROOT::IsImplicitMTEnabled())
      nSlots = ROOT::GetImplicitMTPoolSize();
#endif // R__USE_IMT
   return nSlots;
}

void GetBranchNamesImpl(TTree &t, std::set<std::string> &bNames, std::set<TTree *> &analysedTrees)
{

   if (!analysedTrees.insert(&t).second) {
      return;
   }

   auto branches = t.GetListOfBranches();
   if (branches) {
      for (auto branchObj : *branches) {
         bNames.insert(branchObj->GetName());
      }
   }

   auto friendTrees = t.GetListOfFriends();

   if (!friendTrees)
      return;

   for (auto friendTreeObj : *friendTrees) {
      auto friendTree = ((TFriendElement *)friendTreeObj)->GetTree();
      GetBranchNamesImpl(*friendTree, bNames, analysedTrees);
   }
}

///////////////////////////////////////////////////////////////////////////////
/// Get all the branches names, including the ones of the friend trees
ColumnNames_t GetBranchNames(TTree &t)
{
   std::set<std::string> bNamesSet;
   std::set<TTree *> analysedTrees;
   GetBranchNamesImpl(t, bNamesSet, analysedTrees);
   ColumnNames_t bNames;
   for (auto &bName : bNamesSet)
      bNames.emplace_back(bName);
   return bNames;
}

void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols,
                       const ColumnNames_t &dataSourceColumns)
{
   const std::string definedColStr(definedCol);
   if (treePtr != nullptr) {
      // check if definedCol is already present in TTree
      const auto branch = treePtr->GetBranch(definedColStr.c_str());
      if (branch != nullptr) {
         const auto msg = "branch \"" + definedColStr + "\" already present in TTree";
         throw std::runtime_error(msg);
      }
   }
   // check if definedCol has already been `Define`d in the functional graph
   if (std::find(customCols.begin(), customCols.end(), definedCol) != customCols.end()) {
      const auto msg = "Redefinition of column \"" + definedColStr + "\"";
      throw std::runtime_error(msg);
   }
   // check if definedCol is already present in the DataSource (but has not yet been `Define`d)
   if (!dataSourceColumns.empty()) {
      if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end()) {
         const auto msg = "Redefinition of column \"" + definedColStr + "\" already present in the data-source";
         throw std::runtime_error(msg);
      }
   }
}

void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
{
   if (nTemplateParams != nColumnNames) {
      std::string err_msg = "The number of template parameters specified for the snapshot is ";
      err_msg += std::to_string(nTemplateParams);
      err_msg += " while ";
      err_msg += std::to_string(nColumnNames);
      err_msg += " columns have been specified.";
      throw std::runtime_error(err_msg);
   }
}

/// Choose between local column names or default column names, throw in case of errors.
const ColumnNames_t
SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
{
   if (names.empty()) {
      // use default column names
      if (defaultNames.size() < nRequiredNames)
         throw std::runtime_error(
            std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
            " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
      // return first nRequiredNames default column names
      return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
   } else {
      // use column names provided by the user to this particular transformation/action
      if (names.size() != nRequiredNames) {
         auto msg = std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
                    " required but " + std::to_string(names.size()) + (names.size() == 1 ? " was" : " were") +
                    " provided:";
         for (const auto &name : names)
            msg += " \"" + name + "\",";
         msg.back() = '.';
         throw std::runtime_error(msg);
      }
      return names;
   }
}

ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, TTree *tree, const ColumnNames_t &definedCols,
                                 const ColumnNames_t &dataSourceColumns)
{
   ColumnNames_t unknownColumns;
   for (auto &column : requiredCols) {
      const auto isTreeBranch = (tree != nullptr && tree->GetBranch(column.c_str()) != nullptr);
      if (isTreeBranch)
         continue;
      const auto isCustomColumn = std::find(definedCols.begin(), definedCols.end(), column) != definedCols.end();
      if (isCustomColumn)
         continue;
      const auto isDataSourceColumn =
         std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
      if (isDataSourceColumn)
         continue;
      unknownColumns.emplace_back(column);
   }
   return unknownColumns;
}

bool IsInternalColumn(std::string_view colName)
{
   return 0 == colName.find("tdf") && '_' == colName.back();
}

} // end NS TDF
} // end NS Internal
} // end NS ROOT
<commit_msg>[TDF] Throw exception if we could not deduce the type of a tree branch<commit_after>// Author: Enrico Guiraud, Danilo Piparo CERN  03/2017

/*************************************************************************
 * Copyright (C) 1995-2016, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "RConfigure.h"      // R__USE_IMT
#include "ROOT/TDFNodes.hxx" // ColumnName2ColumnTypeName -> TCustomColumnBase, FindUnknownColumns -> TLoopManager
#include "ROOT/TDFUtils.hxx"
#include "TBranch.h"
#include "TBranchElement.h"
#include "TClassRef.h"
#include "TFriendElement.h"
#include "TROOT.h" // IsImplicitMTEnabled, GetImplicitMTPoolSize

#include <stdexcept>
#include <string>
class TTree;
using namespace ROOT::Detail::TDF;
using namespace ROOT::Experimental::TDF;

namespace ROOT {
namespace Internal {
namespace TDF {

TIgnoreErrorLevelRAII::TIgnoreErrorLevelRAII(int errorIgnoreLevel)
{
   gErrorIgnoreLevel = errorIgnoreLevel;
}
TIgnoreErrorLevelRAII::~TIgnoreErrorLevelRAII()
{
   gErrorIgnoreLevel = fCurIgnoreErrorLevel;
}

/// Return a string containing the type of the given branch. Works both with real TTree branches and with temporary
/// column created by Define. Returns an empty string if type name deduction fails.
std::string
ColumnName2ColumnTypeName(const std::string &colName, TTree *tree, TCustomColumnBase *tmpBranch, TDataSource *ds)
{
   if (ds && ds->HasColumn(colName)) {
      return ds->GetTypeName(colName);
   }

   TBranch *branch = nullptr;
   if (tree)
      branch = tree->GetBranch(colName.c_str());
   if (!branch && !tmpBranch) {
      throw std::runtime_error("Column \"" + colName + "\" is not in a file and has not been defined.");
   }
   if (branch) {
      // this must be a real TTree branch
      static const TClassRef tbranchelRef("TBranchElement");
      if (branch->InheritsFrom(tbranchelRef)) {
         return static_cast<TBranchElement *>(branch)->GetClassName();
      } else { // Try the fundamental type
         std::string_view title(branch->GetTitle());
         char typeCode = title.back();
         std::string type;
         if (typeCode == 'B')
            type = "char";
         else if (typeCode == 'b')
            type = "unsigned char";
         else if (typeCode == 'I')
            type = "int";
         else if (typeCode == 'i')
            type = "unsigned int";
         else if (typeCode == 'S')
            type = "short";
         else if (typeCode == 's')
            type = "unsigned short";
         else if (typeCode == 'D')
            type = "double";
         else if (typeCode == 'F')
            type = "float";
         else if (typeCode == 'n')
            type = "Float_t";
         else if (typeCode == 'L')
            type = "Long64_t";
         else if (typeCode == 'l')
            type = "ULong64_t";
         else if (typeCode == 'O')
            type = "bool";
         if (type.empty())
            throw std::runtime_error("could not deduce type of branch " + std::string(title));
         if (title.size() > 3 && title[title.size() - 3] == ']') {
            // title has the form "varname[size]/X", i.e. it refers to an array (doesn't matter if size is fixed or not)
            // TDataFrame reads it as a TArrayBranch
            return "ROOT::Experimental::TDF::TArrayBranch<" + type + ">";
         } else {
            return type;
         }
      }
   } else {
      // this must be a temporary branch
      const auto &type_id = tmpBranch->GetTypeId();
      if (auto c = TClass::GetClass(type_id)) {
         return c->GetName();
      } else if (type_id == typeid(char))
         return "char";
      else if (type_id == typeid(unsigned char))
         return "unsigned char";
      else if (type_id == typeid(int))
         return "int";
      else if (type_id == typeid(unsigned int))
         return "unsigned int";
      else if (type_id == typeid(short))
         return "short";
      else if (type_id == typeid(unsigned short))
         return "unsigned short";
      else if (type_id == typeid(long))
         return "long";
      else if (type_id == typeid(unsigned long))
         return "unsigned long";
      else if (type_id == typeid(double))
         return "double";
      else if (type_id == typeid(float))
         return "float";
      else if (type_id == typeid(Long64_t))
         return "Long64_t";
      else if (type_id == typeid(ULong64_t))
         return "ULong64_t";
      else if (type_id == typeid(bool))
         return "bool";
      else {
         std::string msg("Cannot deduce type of temporary column ");
         msg += colName.c_str();
         msg += ". The typename is ";
         msg += tmpBranch->GetTypeId().name();
         msg += ".";
         throw std::runtime_error(msg);
      }
   }
   // we never reach here
}

const char *ToConstCharPtr(const char *s)
{
   return s;
}

const char *ToConstCharPtr(const std::string &s)
{
   return s.c_str();
}

unsigned int GetNSlots()
{
   unsigned int nSlots = 1;
#ifdef R__USE_IMT
   if (ROOT::IsImplicitMTEnabled())
      nSlots = ROOT::GetImplicitMTPoolSize();
#endif // R__USE_IMT
   return nSlots;
}

void GetBranchNamesImpl(TTree &t, std::set<std::string> &bNames, std::set<TTree *> &analysedTrees)
{

   if (!analysedTrees.insert(&t).second) {
      return;
   }

   auto branches = t.GetListOfBranches();
   if (branches) {
      for (auto branchObj : *branches) {
         bNames.insert(branchObj->GetName());
      }
   }

   auto friendTrees = t.GetListOfFriends();

   if (!friendTrees)
      return;

   for (auto friendTreeObj : *friendTrees) {
      auto friendTree = ((TFriendElement *)friendTreeObj)->GetTree();
      GetBranchNamesImpl(*friendTree, bNames, analysedTrees);
   }
}

///////////////////////////////////////////////////////////////////////////////
/// Get all the branches names, including the ones of the friend trees
ColumnNames_t GetBranchNames(TTree &t)
{
   std::set<std::string> bNamesSet;
   std::set<TTree *> analysedTrees;
   GetBranchNamesImpl(t, bNamesSet, analysedTrees);
   ColumnNames_t bNames;
   for (auto &bName : bNamesSet)
      bNames.emplace_back(bName);
   return bNames;
}

void CheckCustomColumn(std::string_view definedCol, TTree *treePtr, const ColumnNames_t &customCols,
                       const ColumnNames_t &dataSourceColumns)
{
   const std::string definedColStr(definedCol);
   if (treePtr != nullptr) {
      // check if definedCol is already present in TTree
      const auto branch = treePtr->GetBranch(definedColStr.c_str());
      if (branch != nullptr) {
         const auto msg = "branch \"" + definedColStr + "\" already present in TTree";
         throw std::runtime_error(msg);
      }
   }
   // check if definedCol has already been `Define`d in the functional graph
   if (std::find(customCols.begin(), customCols.end(), definedCol) != customCols.end()) {
      const auto msg = "Redefinition of column \"" + definedColStr + "\"";
      throw std::runtime_error(msg);
   }
   // check if definedCol is already present in the DataSource (but has not yet been `Define`d)
   if (!dataSourceColumns.empty()) {
      if (std::find(dataSourceColumns.begin(), dataSourceColumns.end(), definedCol) != dataSourceColumns.end()) {
         const auto msg = "Redefinition of column \"" + definedColStr + "\" already present in the data-source";
         throw std::runtime_error(msg);
      }
   }
}

void CheckSnapshot(unsigned int nTemplateParams, unsigned int nColumnNames)
{
   if (nTemplateParams != nColumnNames) {
      std::string err_msg = "The number of template parameters specified for the snapshot is ";
      err_msg += std::to_string(nTemplateParams);
      err_msg += " while ";
      err_msg += std::to_string(nColumnNames);
      err_msg += " columns have been specified.";
      throw std::runtime_error(err_msg);
   }
}

/// Choose between local column names or default column names, throw in case of errors.
const ColumnNames_t
SelectColumns(unsigned int nRequiredNames, const ColumnNames_t &names, const ColumnNames_t &defaultNames)
{
   if (names.empty()) {
      // use default column names
      if (defaultNames.size() < nRequiredNames)
         throw std::runtime_error(
            std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
            " required but none were provided and the default list has size " + std::to_string(defaultNames.size()));
      // return first nRequiredNames default column names
      return ColumnNames_t(defaultNames.begin(), defaultNames.begin() + nRequiredNames);
   } else {
      // use column names provided by the user to this particular transformation/action
      if (names.size() != nRequiredNames) {
         auto msg = std::to_string(nRequiredNames) + " column name" + (nRequiredNames == 1 ? " is" : "s are") +
                    " required but " + std::to_string(names.size()) + (names.size() == 1 ? " was" : " were") +
                    " provided:";
         for (const auto &name : names)
            msg += " \"" + name + "\",";
         msg.back() = '.';
         throw std::runtime_error(msg);
      }
      return names;
   }
}

ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, TTree *tree, const ColumnNames_t &definedCols,
                                 const ColumnNames_t &dataSourceColumns)
{
   ColumnNames_t unknownColumns;
   for (auto &column : requiredCols) {
      const auto isTreeBranch = (tree != nullptr && tree->GetBranch(column.c_str()) != nullptr);
      if (isTreeBranch)
         continue;
      const auto isCustomColumn = std::find(definedCols.begin(), definedCols.end(), column) != definedCols.end();
      if (isCustomColumn)
         continue;
      const auto isDataSourceColumn =
         std::find(dataSourceColumns.begin(), dataSourceColumns.end(), column) != dataSourceColumns.end();
      if (isDataSourceColumn)
         continue;
      unknownColumns.emplace_back(column);
   }
   return unknownColumns;
}

bool IsInternalColumn(std::string_view colName)
{
   return 0 == colName.find("tdf") && '_' == colName.back();
}

} // end NS TDF
} // end NS Internal
} // end NS ROOT
<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "amr_includes.H"

#include <sc_statistics.h>

#define FCLAW2D_STATS_SET(stats,ddata,NAME) do {                               \
    SC_CHECK_ABORT (!(ddata)->timers[FCLAW2D_TIMER_ ## NAME].running,          \
                    "Timer " #NAME " still running in amrreset");              \
    sc_stats_set1 ((stats) + FCLAW2D_TIMER_ ## NAME,                           \
                   (ddata)->timers[FCLAW2D_TIMER_ ## NAME].cumulative, #NAME); \
} while (0)

void amrreset(fclaw2d_domain_t **domain)
{
    fclaw2d_domain_data_t *ddata = get_domain_data (*domain);

    for(int i = 0; i < (*domain)->num_blocks; i++)
    {
        fclaw2d_block_t *block = (*domain)->blocks + i;
        fclaw2d_block_data_t *bd = (fclaw2d_block_data_t *) block->user;

        for(int j = 0; j < block->num_patches; j++)
        {
            fclaw2d_patch_t *patch = block->patches + j;
            fclaw2d_patch_data_t *pdata = (fclaw2d_patch_data_t *) patch->user;
            delete pdata->cp;
            pdata->cp = NULL;

            ++ddata->count_delete_clawpatch;

            FCLAW2D_FREE (pdata);
            patch->user = NULL;
        }

        FCLAW2D_FREE (bd);
        block->user = NULL;
    }

    // Free old parallel ghost patch data structure, must exist by construction.
    delete_ghost_patches(*domain);
    fclaw2d_domain_exchange_t *e_old = get_domain_exchange_data(*domain);
    fclaw2d_domain_free_after_exchange (*domain, e_old);

    // Output memory discrepancy for the ClawPatch
    if (ddata->count_set_clawpatch != ddata->count_delete_clawpatch) {
        printf ("[%d] This domain had Clawpatch set %d and deleted %d times\n",
                (*domain)->mpirank,
                ddata->count_set_clawpatch, ddata->count_delete_clawpatch);
    }

    // Evaluate timers if this domain has not been superseded yet.
    if (ddata->is_latest_domain) {
        sc_statinfo_t stats[FCLAW2D_TIMER_COUNT];

        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_WALLTIME]);

        FCLAW2D_STATS_SET (stats, ddata, INIT);
        FCLAW2D_STATS_SET (stats, ddata, REGRID);
        FCLAW2D_STATS_SET (stats, ddata, OUTPUT);
        FCLAW2D_STATS_SET (stats, ddata, CHECK);
        FCLAW2D_STATS_SET (stats, ddata, ADVANCE);
        FCLAW2D_STATS_SET (stats, ddata, EXCHANGE);
        FCLAW2D_STATS_SET (stats, ddata, WALLTIME);
        sc_stats_set1 (&stats[FCLAW2D_TIMER_UNACCOUNTED],
                       ddata->timers[FCLAW2D_TIMER_WALLTIME].cumulative -
                       (ddata->timers[FCLAW2D_TIMER_INIT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_REGRID].cumulative +
                        ddata->timers[FCLAW2D_TIMER_OUTPUT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_CHECK].cumulative +
                        ddata->timers[FCLAW2D_TIMER_ADVANCE].cumulative +
                        ddata->timers[FCLAW2D_TIMER_EXCHANGE].cumulative),
                       "UNACCOUNTED");
        sc_stats_compute ((*domain)->mpicomm, FCLAW2D_TIMER_COUNT, stats);
        sc_stats_print (sc_package_id, SC_LP_PRODUCTION, FCLAW2D_TIMER_COUNT,
                        stats, 1, 0);
    }

    delete_domain_data(*domain);  // Delete allocated pointers to set of functions.

    fclaw2d_domain_destroy(*domain);
    *domain = NULL;
}
<commit_msg>Print statistics summary line<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "amr_includes.H"

#include <sc_statistics.h>

#define FCLAW2D_STATS_SET(stats,ddata,NAME) do {                               \
    SC_CHECK_ABORT (!(ddata)->timers[FCLAW2D_TIMER_ ## NAME].running,          \
                    "Timer " #NAME " still running in amrreset");              \
    sc_stats_set1 ((stats) + FCLAW2D_TIMER_ ## NAME,                           \
                   (ddata)->timers[FCLAW2D_TIMER_ ## NAME].cumulative, #NAME); \
} while (0)

void amrreset(fclaw2d_domain_t **domain)
{
    fclaw2d_domain_data_t *ddata = get_domain_data (*domain);

    for(int i = 0; i < (*domain)->num_blocks; i++)
    {
        fclaw2d_block_t *block = (*domain)->blocks + i;
        fclaw2d_block_data_t *bd = (fclaw2d_block_data_t *) block->user;

        for(int j = 0; j < block->num_patches; j++)
        {
            fclaw2d_patch_t *patch = block->patches + j;
            fclaw2d_patch_data_t *pdata = (fclaw2d_patch_data_t *) patch->user;
            delete pdata->cp;
            pdata->cp = NULL;

            ++ddata->count_delete_clawpatch;

            FCLAW2D_FREE (pdata);
            patch->user = NULL;
        }

        FCLAW2D_FREE (bd);
        block->user = NULL;
    }

    // Free old parallel ghost patch data structure, must exist by construction.
    delete_ghost_patches(*domain);
    fclaw2d_domain_exchange_t *e_old = get_domain_exchange_data(*domain);
    fclaw2d_domain_free_after_exchange (*domain, e_old);

    // Output memory discrepancy for the ClawPatch
    if (ddata->count_set_clawpatch != ddata->count_delete_clawpatch) {
        printf ("[%d] This domain had Clawpatch set %d and deleted %d times\n",
                (*domain)->mpirank,
                ddata->count_set_clawpatch, ddata->count_delete_clawpatch);
    }

    // Evaluate timers if this domain has not been superseded yet.
    if (ddata->is_latest_domain) {
        sc_statinfo_t stats[FCLAW2D_TIMER_COUNT];

        fclaw2d_timer_stop (&ddata->timers[FCLAW2D_TIMER_WALLTIME]);

        FCLAW2D_STATS_SET (stats, ddata, INIT);
        FCLAW2D_STATS_SET (stats, ddata, REGRID);
        FCLAW2D_STATS_SET (stats, ddata, OUTPUT);
        FCLAW2D_STATS_SET (stats, ddata, CHECK);
        FCLAW2D_STATS_SET (stats, ddata, ADVANCE);
        FCLAW2D_STATS_SET (stats, ddata, EXCHANGE);
        FCLAW2D_STATS_SET (stats, ddata, WALLTIME);
        sc_stats_set1 (&stats[FCLAW2D_TIMER_UNACCOUNTED],
                       ddata->timers[FCLAW2D_TIMER_WALLTIME].cumulative -
                       (ddata->timers[FCLAW2D_TIMER_INIT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_REGRID].cumulative +
                        ddata->timers[FCLAW2D_TIMER_OUTPUT].cumulative +
                        ddata->timers[FCLAW2D_TIMER_CHECK].cumulative +
                        ddata->timers[FCLAW2D_TIMER_ADVANCE].cumulative +
                        ddata->timers[FCLAW2D_TIMER_EXCHANGE].cumulative),
                       "UNACCOUNTED");
        sc_stats_compute ((*domain)->mpicomm, FCLAW2D_TIMER_COUNT, stats);
        sc_stats_print (sc_package_id, SC_LP_PRODUCTION, FCLAW2D_TIMER_COUNT,
                        stats, 1, 0);
        SC_GLOBAL_PRODUCTIONF ("Procs %d advance %g exchange %g regrid %g\n",
                               (*domain)->mpisize,
                               stats[FCLAW2D_TIMER_ADVANCE].average,
                               stats[FCLAW2D_TIMER_EXCHANGE].average,
                               stats[FCLAW2D_TIMER_REGRID].average);
    }

    delete_domain_data(*domain);  // Delete allocated pointers to set of functions.

    fclaw2d_domain_destroy(*domain);
    *domain = NULL;
}
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2020 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include "image.h"
#include "../../../common/sys/string.h"

#include <map>
#include <iostream>

namespace embree
{
  double compareImages(Ref<Image> image0, Ref<Image> image1)
  {
    /* compare image size */
    const size_t width = image0->width;
    const size_t height = image0->height;
    if (image1->width != width) return 1;
    if (image1->height != height) return 1;

    /* compare both images */
    double diff = 0.0;
    for (size_t y=0; y<height; y++)
    {
      for (size_t x=0; x<width; x++)
      {
        const Color c0 = image0->get(x,y);
        const Color c1 = image1->get(x,y);
        diff += sqr(fabs(c0.r - c1.r))/3.0f;
        diff += sqr(fabs(c0.g - c1.g))/3.0f;
        diff += sqr(fabs(c0.b - c1.b))/3.0f;
      }
    }

    return diff;
  }

  /*! loads an image from a file with auto-detection of format */
  Ref<Image> loadImageFromDisk(const FileName& fileName)
  {
    std::string ext = toLowerCase(fileName.ext());

#ifdef EMBREE_TUTORIALS_LIBPNG
    if (ext == "png" ) return loadPNG(fileName);
#endif

#ifdef EMBREE_TUTORIALS_LIBJPEG
    if (ext == "jpg" ) return loadJPEG(fileName);
#endif

#ifdef USE_OPENIMAGEIO
    if (ext == "bmp" ) return loadOIIO(fileName);
    if (ext == "gif" ) return loadOIIO(fileName);
    if (ext == "tga" ) return loadOIIO(fileName);
    if (ext == "tif" ) return loadOIIO(fileName);
    if (ext == "tiff") return loadOIIO(fileName);
    if (ext == "png" ) return loadOIIO(fileName);
    if (ext == "jpg" ) return loadOIIO(fileName);
#endif

    if (ext == "pfm" ) return loadPFM(fileName);
    if (ext == "ppm" ) return loadPPM(fileName);
    if (ext == "tga" ) return loadTGA(fileName);
    THROW_RUNTIME_ERROR("image format " + ext + " not supported");
  }

  static std::map<std::string,Ref<Image> > image_cache;

  /*! loads an image from a file with auto-detection of format */
  Ref<Image> loadImage(const FileName& fileName, bool cache)
  {
    if (!cache)
      return loadImageFromDisk(fileName);

    if (image_cache.find(fileName) == image_cache.end())
      image_cache[fileName] = loadImageFromDisk(fileName);

    return image_cache[fileName];
  }

  /*! stores an image to file with auto-detection of format */
  void storeImage(const Ref<Image>& img, const FileName& fileName)
  {
    std::string ext = toLowerCase(fileName.ext());

#ifdef EMBREE_TUTORIALS_LIBJPEG
    if (ext == "jpg" ) { storeJPEG(img, fileName);  return; }
#endif

#ifdef USE_OPENIMAGEIO
    if (ext == "bmp" ) { storeOIIO(img, fileName);  return; }
    if (ext == "gif" ) { storeOIIO(img, fileName);  return; }
    if (ext == "tga" ) { storeOIIO(img, fileName);  return; }
    if (ext == "tif" ) { storeOIIO(img, fileName);  return; }
    if (ext == "tiff") { storeOIIO(img, fileName);  return; }
    if (ext == "png" ) { storeOIIO(img, fileName);  return; }
    if (ext == "jpg" ) { storeOIIO(img, fileName);  return; }
#endif

    if (ext == "pfm" ) { storePFM(img, fileName);  return; }
    if (ext == "ppm" ) { storePPM(img, fileName);  return; }
    if (ext == "tga" ) { storeTga(img, fileName);  return; }
    THROW_RUNTIME_ERROR("image format " + ext + " not supported");
  }

  /*! template instantiations */
  template class ImageT<Col3uc>;
  template class ImageT<Col3f>;

}
<commit_msg>compareImage returns maximal error if with or height of images mismatches<commit_after>// ======================================================================== //
// Copyright 2009-2020 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include "image.h"
#include "../../../common/sys/string.h"

#include <map>
#include <iostream>

namespace embree
{
  double compareImages(Ref<Image> image0, Ref<Image> image1)
  {
    /* compare image size */
    const size_t width = image0->width;
    const size_t height = image0->height;
    if (image1->width != width) return inf;
    if (image1->height != height) return inf;

    /* compare both images */
    double diff = 0.0;
    for (size_t y=0; y<height; y++)
    {
      for (size_t x=0; x<width; x++)
      {
        const Color c0 = image0->get(x,y);
        const Color c1 = image1->get(x,y);
        diff += sqr(fabs(c0.r - c1.r))/3.0f;
        diff += sqr(fabs(c0.g - c1.g))/3.0f;
        diff += sqr(fabs(c0.b - c1.b))/3.0f;
      }
    }

    return diff;
  }

  /*! loads an image from a file with auto-detection of format */
  Ref<Image> loadImageFromDisk(const FileName& fileName)
  {
    std::string ext = toLowerCase(fileName.ext());

#ifdef EMBREE_TUTORIALS_LIBPNG
    if (ext == "png" ) return loadPNG(fileName);
#endif

#ifdef EMBREE_TUTORIALS_LIBJPEG
    if (ext == "jpg" ) return loadJPEG(fileName);
#endif

#ifdef USE_OPENIMAGEIO
    if (ext == "bmp" ) return loadOIIO(fileName);
    if (ext == "gif" ) return loadOIIO(fileName);
    if (ext == "tga" ) return loadOIIO(fileName);
    if (ext == "tif" ) return loadOIIO(fileName);
    if (ext == "tiff") return loadOIIO(fileName);
    if (ext == "png" ) return loadOIIO(fileName);
    if (ext == "jpg" ) return loadOIIO(fileName);
#endif

    if (ext == "pfm" ) return loadPFM(fileName);
    if (ext == "ppm" ) return loadPPM(fileName);
    if (ext == "tga" ) return loadTGA(fileName);
    THROW_RUNTIME_ERROR("image format " + ext + " not supported");
  }

  static std::map<std::string,Ref<Image> > image_cache;

  /*! loads an image from a file with auto-detection of format */
  Ref<Image> loadImage(const FileName& fileName, bool cache)
  {
    if (!cache)
      return loadImageFromDisk(fileName);

    if (image_cache.find(fileName) == image_cache.end())
      image_cache[fileName] = loadImageFromDisk(fileName);

    return image_cache[fileName];
  }

  /*! stores an image to file with auto-detection of format */
  void storeImage(const Ref<Image>& img, const FileName& fileName)
  {
    std::string ext = toLowerCase(fileName.ext());

#ifdef EMBREE_TUTORIALS_LIBJPEG
    if (ext == "jpg" ) { storeJPEG(img, fileName);  return; }
#endif

#ifdef USE_OPENIMAGEIO
    if (ext == "bmp" ) { storeOIIO(img, fileName);  return; }
    if (ext == "gif" ) { storeOIIO(img, fileName);  return; }
    if (ext == "tga" ) { storeOIIO(img, fileName);  return; }
    if (ext == "tif" ) { storeOIIO(img, fileName);  return; }
    if (ext == "tiff") { storeOIIO(img, fileName);  return; }
    if (ext == "png" ) { storeOIIO(img, fileName);  return; }
    if (ext == "jpg" ) { storeOIIO(img, fileName);  return; }
#endif

    if (ext == "pfm" ) { storePFM(img, fileName);  return; }
    if (ext == "ppm" ) { storePPM(img, fileName);  return; }
    if (ext == "tga" ) { storeTga(img, fileName);  return; }
    THROW_RUNTIME_ERROR("image format " + ext + " not supported");
  }

  /*! template instantiations */
  template class ImageT<Col3uc>;
  template class ImageT<Col3f>;

}
<|endoftext|>


<commit_before>/*
Copyright (c) 2017 InversePalindrome
VariadicPoker - HoleCards.cpp
InversePalindrome.com
*/

#include "HoleCards.hpp"

HoleCards::HoleCards() :
	holeCards()
{
}

HoleCards::HoleCards(const std::vector<Card>& holeCards) :
	holeCards(holeCards)
{
}

std::vector<Card> HoleCards::getCards() const
{
	return this->holeCards;
}

void HoleCards::setCards(const std::vector<Card>& holeCards)
{
	this->holeCards = holeCards;
}

void HoleCards::addCard(const Card& card)
{
	this->holeCards.push_back(card);
}

void HoleCards::removeCard(const Card& card)
{
	this->holeCards.erase(std::remove(this->holeCards.begin(), this->holeCards.end(), card), this->holeCards.end());
}

void HoleCards::removeCards()
{
	this->holeCards.clear();
}

bool HoleCards::hasCards() const
{
	return this->holeCards.empty();
}

std::string HoleCards::toString() const
{
	std::string holeCardRepresentation = "| ";
	for (const Card& card: this->holeCards)
	{
		holeCardRepresentation += card.toString() + " | ";
	}

	return holeCardRepresentation;
}
<commit_msg>Update HoleCards.cpp<commit_after>/*
Copyright (c) 2017 InversePalindrome
VariadicPoker - HoleCards.cpp
InversePalindrome.com
*/

#include "HoleCards.hpp"

HoleCards::HoleCards() :
	holeCards()
{
}

HoleCards::HoleCards(const std::vector<Card>& holeCards) :
	holeCards(holeCards)
{
}

std::vector<Card> HoleCards::getCards() const
{
	return this->holeCards;
}

void HoleCards::setCards(const std::vector<Card>& holeCards)
{
	this->holeCards = holeCards;
}

void HoleCards::addCard(const Card& card)
{
	this->holeCards.push_back(card);
}

void HoleCards::removeCard(const Card& card)
{
	this->holeCards.erase(std::remove(this->holeCards.begin(), this->holeCards.end(), card), this->holeCards.end());
}

void HoleCards::removeCards()
{
	this->holeCards.clear();
}

bool HoleCards::hasCards() const
{
	return !this->holeCards.empty();
}

std::string HoleCards::toString() const
{
	std::string holeCardRepresentation = "| ";
	for (const auto& card : this->holeCards)
	{
		holeCardRepresentation += card.toString() + " | ";
	}

	return holeCardRepresentation;
}

<|endoftext|>


<commit_before>#ifndef _FILERROR_HXX_

namespace fileaccess {

// Error codes used to deliver the resulting exceptions
#define LOWEST_FREE_ERROR                               72

#define TASKHANDLER_NO_ERROR                            0
#define TASKHANDLER_UNSUPPORTED_COMMAND                 1
#define TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT   2
#define TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT   3
#define TASKHANDLING_WRONG_OPEN_ARGUMENT                4
#define TASKHANDLING_WRONG_DELETE_ARGUMENT              5
#define TASKHANDLING_WRONG_TRANSFER_ARGUMENT            6
#define TASKHANDLING_WRONG_INSERT_ARGUMENT              7

#define TASKHANDLING_UNSUPPORTED_OPEN_MODE              8

#define TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND      9
#define TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND    10

#define TASKHANDLING_OPEN_FILE_FOR_PAGING              11
#define TASKHANDLING_NOTCONNECTED_FOR_PAGING           12
#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING     13
#define TASKHANDLING_IOEXCEPTION_FOR_PAGING            14
#define TASKHANDLING_READING_FILE_FOR_PAGING           15

#define TASKHANDLING_OPEN_FOR_INPUTSTREAM              16
#define TASKHANDLING_OPEN_FOR_STREAM                   17
#define TASKHANDLING_OPEN_FOR_DIRECTORYLISTING         18

#define TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND   22
#define TASKHANDLING_NONAMESET_INSERT_COMMAND          23
#define TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND      24

#define TASKHANDLING_ANYOTHER_WRITE                    25   // not used
#define TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE        26
#define TASKHANDLING_NO_OPEN_FILE_FOR_WRITE            27
#define TASKHANDLING_NOTCONNECTED_FOR_WRITE            28
#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE      29
#define TASKHANDLING_IOEXCEPTION_FOR_WRITE             30
#define TASKHANDLING_FILEIOERROR_FOR_WRITE             31
#define TASKHANDLING_FILEIOERROR_FOR_NO_SPACE          71
#define TASKHANDLING_FILESIZE_FOR_WRITE                32
#define TASKHANDLING_INPUTSTREAM_FOR_WRITE             33
#define TASKHANDLING_NOREPLACE_FOR_WRITE               34
#define TASKHANDLING_ENSUREDIR_FOR_WRITE               35

#define TASKHANDLING_FOLDER_EXISTS_MKDIR               69
#define TASKHANDLING_INVALID_NAME_MKDIR                70
#define TASKHANDLING_CREATEDIRECTORY_MKDIR             36

#define TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE        38
#define TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE        39
#define TASKHANDLING_OPENDIRECTORY_FOR_REMOVE          40
#define TASKHANDLING_DELETEFILE_FOR_REMOVE             41
#define TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE        42
#define TASKHANDLING_FILETYPE_FOR_REMOVE               43
#define TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE   44
#define TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE     45

#define TASKHANDLING_TRANSFER_ACCESSINGROOT            46
#define TASKHANDLING_TRANSFER_INVALIDSCHEME            47
#define TASKHANDLING_TRANSFER_INVALIDURL               48
#define TASKHANDLING_TRANSFER_MOUNTPOINTS              49
#define TASKHANDLING_TRANSFER_DESTFILETYPE             50
#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCE           51
#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT       52
#define TASKHANDLING_KEEPERROR_FOR_MOVE                53
#define TASKHANDLING_NAMECLASH_FOR_MOVE                54
#define TASKHANDLING_NAMECLASHMOVE_FOR_MOVE            55
#define TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE         56
#define TASKHANDLING_OVERWRITE_FOR_MOVE                57
#define TASKHANDLING_RENAME_FOR_MOVE                   58
#define TASKHANDLING_RENAMEMOVE_FOR_MOVE               59

#define TASKHANDLING_TRANSFER_BY_COPY_SOURCE           60
#define TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT       61
#define TASKHANDLING_KEEPERROR_FOR_COPY                62
#define TASKHANDLING_OVERWRITE_FOR_COPY                63
#define TASKHANDLING_RENAME_FOR_COPY                   64
#define TASKHANDLING_RENAMEMOVE_FOR_COPY               65
#define TASKHANDLING_NAMECLASH_FOR_COPY                66
#define TASKHANDLING_NAMECLASHMOVE_FOR_COPY            67
#define TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY         68

}

#endif

<commit_msg>INTEGRATION: CWS relocinst (1.6.96); FILE MERGED 2004/04/22 11:31:16 kso 1.6.96.1: #116448# - Does no longer use ooSetupInstallPath and OfficeInstall config items.          - removed mountpoints support (not needed any longer).  CVS: ----------------------------------------------------------------------<commit_after>#ifndef _FILERROR_HXX_

namespace fileaccess {

// Error codes used to deliver the resulting exceptions
#define LOWEST_FREE_ERROR                               72

#define TASKHANDLER_NO_ERROR                            0
#define TASKHANDLER_UNSUPPORTED_COMMAND                 1
#define TASKHANDLING_WRONG_SETPROPERTYVALUES_ARGUMENT   2
#define TASKHANDLING_WRONG_GETPROPERTYVALUES_ARGUMENT   3
#define TASKHANDLING_WRONG_OPEN_ARGUMENT                4
#define TASKHANDLING_WRONG_DELETE_ARGUMENT              5
#define TASKHANDLING_WRONG_TRANSFER_ARGUMENT            6
#define TASKHANDLING_WRONG_INSERT_ARGUMENT              7

#define TASKHANDLING_UNSUPPORTED_OPEN_MODE              8

#define TASKHANDLING_DELETED_STATE_IN_OPEN_COMMAND      9
#define TASKHANDLING_INSERTED_STATE_IN_OPEN_COMMAND    10

#define TASKHANDLING_OPEN_FILE_FOR_PAGING              11
#define TASKHANDLING_NOTCONNECTED_FOR_PAGING           12
#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_PAGING     13
#define TASKHANDLING_IOEXCEPTION_FOR_PAGING            14
#define TASKHANDLING_READING_FILE_FOR_PAGING           15

#define TASKHANDLING_OPEN_FOR_INPUTSTREAM              16
#define TASKHANDLING_OPEN_FOR_STREAM                   17
#define TASKHANDLING_OPEN_FOR_DIRECTORYLISTING         18

#define TASKHANDLING_NOFRESHINSERT_IN_INSERT_COMMAND   22
#define TASKHANDLING_NONAMESET_INSERT_COMMAND          23
#define TASKHANDLING_NOCONTENTTYPE_INSERT_COMMAND      24

#define TASKHANDLING_ANYOTHER_WRITE                    25   // not used
#define TASKHANDLING_NO_OPEN_FILE_FOR_OVERWRITE        26
#define TASKHANDLING_NO_OPEN_FILE_FOR_WRITE            27
#define TASKHANDLING_NOTCONNECTED_FOR_WRITE            28
#define TASKHANDLING_BUFFERSIZEEXCEEDED_FOR_WRITE      29
#define TASKHANDLING_IOEXCEPTION_FOR_WRITE             30
#define TASKHANDLING_FILEIOERROR_FOR_WRITE             31
#define TASKHANDLING_FILEIOERROR_FOR_NO_SPACE          71
#define TASKHANDLING_FILESIZE_FOR_WRITE                32
#define TASKHANDLING_INPUTSTREAM_FOR_WRITE             33
#define TASKHANDLING_NOREPLACE_FOR_WRITE               34
#define TASKHANDLING_ENSUREDIR_FOR_WRITE               35

#define TASKHANDLING_FOLDER_EXISTS_MKDIR               69
#define TASKHANDLING_INVALID_NAME_MKDIR                70
#define TASKHANDLING_CREATEDIRECTORY_MKDIR             36

#define TASKHANDLING_NOSUCHFILEORDIR_FOR_REMOVE        38
#define TASKHANDLING_VALIDFILESTATUS_FOR_REMOVE        39
#define TASKHANDLING_OPENDIRECTORY_FOR_REMOVE          40
#define TASKHANDLING_DELETEFILE_FOR_REMOVE             41
#define TASKHANDLING_DELETEDIRECTORY_FOR_REMOVE        42
#define TASKHANDLING_FILETYPE_FOR_REMOVE               43
#define TASKHANDLING_VALIDFILESTATUSWHILE_FOR_REMOVE   44
#define TASKHANDLING_DIRECTORYEXHAUSTED_FOR_REMOVE     45

#define TASKHANDLING_TRANSFER_ACCESSINGROOT            46
#define TASKHANDLING_TRANSFER_INVALIDSCHEME            47
#define TASKHANDLING_TRANSFER_INVALIDURL               48
#define TASKHANDLING_TRANSFER_DESTFILETYPE             50
#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCE           51
#define TASKHANDLING_TRANSFER_BY_MOVE_SOURCESTAT       52
#define TASKHANDLING_KEEPERROR_FOR_MOVE                53
#define TASKHANDLING_NAMECLASH_FOR_MOVE                54
#define TASKHANDLING_NAMECLASHMOVE_FOR_MOVE            55
#define TASKHANDLING_NAMECLASHSUPPORT_FOR_MOVE         56
#define TASKHANDLING_OVERWRITE_FOR_MOVE                57
#define TASKHANDLING_RENAME_FOR_MOVE                   58
#define TASKHANDLING_RENAMEMOVE_FOR_MOVE               59

#define TASKHANDLING_TRANSFER_BY_COPY_SOURCE           60
#define TASKHANDLING_TRANSFER_BY_COPY_SOURCESTAT       61
#define TASKHANDLING_KEEPERROR_FOR_COPY                62
#define TASKHANDLING_OVERWRITE_FOR_COPY                63
#define TASKHANDLING_RENAME_FOR_COPY                   64
#define TASKHANDLING_RENAMEMOVE_FOR_COPY               65
#define TASKHANDLING_NAMECLASH_FOR_COPY                66
#define TASKHANDLING_NAMECLASHMOVE_FOR_COPY            67
#define TASKHANDLING_NAMECLASHSUPPORT_FOR_COPY         68

}

#endif

<|endoftext|>