<commit_before>/**
 * Copyright © 2016 IBM 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 <cstdlib>
#include <experimental/filesystem>
#include <memory>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Control/Device/error.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>
#include "sysfs.hpp"
#include "util.hpp"
#include <fstream>

using namespace phosphor::logging;

std::string findHwmon(const std::string& ofNode)
{
    namespace fs = std::experimental::filesystem;
    static constexpr auto hwmonRoot = "/sys/class/hwmon";
    static constexpr auto ofRoot = "/sys/firmware/devicetree/base";

    fs::path fullOfPath{ofRoot};
    fullOfPath /= ofNode;
    fs::path fullOfPathPhandle{fullOfPath};
    fullOfPathPhandle /= "phandle";

    for (const auto& hwmonInst : fs::directory_iterator(hwmonRoot))
    {
        auto path = hwmonInst.path();
        path /= "of_node";

        if (fs::canonical(path) != fullOfPath)
        {
            // Try to find HWMON instance via phandle values.
            // Used for IIO device drivers.
            path /= "io-channels";
            if (fs::exists(path) && fs::exists(fullOfPathPhandle))
            {
                std::ifstream ioChannelsFile(path);
                std::ifstream pHandleFile(fullOfPathPhandle);

                uint32_t ioChannelsValue;
                uint32_t pHandleValue;

                try
                {
                    ioChannelsFile.read(reinterpret_cast<char*>(&ioChannelsValue),
                                        sizeof(ioChannelsValue));
                    pHandleFile.read(reinterpret_cast<char*>(&pHandleValue),
                                     sizeof(pHandleValue));

                    if (ioChannelsValue == pHandleValue)
                    {
                        return hwmonInst.path();
                    }
                }
                catch (const std::exception& e)
                {
                    log<level::INFO>(e.what());
                }

            }
            continue;
        }

        return hwmonInst.path();
    }

    return std::string();
}

int readSysfsWithCallout(const std::string& root,
                         const std::string& instance,
                         const std::string& type,
                         const std::string& id,
                         const std::string& sensor)
{
    namespace fs = std::experimental::filesystem;

    int value = 0;
    std::ifstream ifs;
    fs::path instancePath{root};
    instancePath /= instance;
    std::string fullPath = make_sysfs_path(instancePath,
                                           type, id, sensor);

    ifs.exceptions(std::ifstream::failbit
                   | std::ifstream::badbit
                   | std::ifstream::eofbit);
    try
    {
        ifs.open(fullPath);
        ifs >> value;
    }
    catch (const std::exception& e)
    {
        // Too many GCC bugs (53984, 66145) to do
        // this the right way...

        // errno should still reflect the error from the failing open
        // or read system calls that got us here.
        auto rc = errno;
        instancePath /= "device";
        using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
        report<ReadFailure>(
            xyz::openbmc_project::Sensor::Device::
                ReadFailure::CALLOUT_ERRNO(rc),
            xyz::openbmc_project::Sensor::Device::
                ReadFailure::CALLOUT_DEVICE_PATH(
                    fs::canonical(instancePath).c_str()));

        exit(EXIT_FAILURE);
    }

    return value;
}

uint64_t writeSysfsWithCallout(const uint64_t& value,
                               const std::string& root,
                               const std::string& instance,
                               const std::string& type,
                               const std::string& id,
                               const std::string& sensor)
{
    namespace fs = std::experimental::filesystem;

    std::string valueStr = std::to_string(value);
    std::ofstream ofs;
    fs::path instancePath{root};
    instancePath /= instance;
    std::string fullPath = make_sysfs_path(instancePath,
                                           type, id, sensor);

    ofs.exceptions(std::ofstream::failbit
                   | std::ofstream::badbit
                   | std::ofstream::eofbit);
    try
    {
        ofs.open(fullPath);
        ofs << valueStr;
    }
    catch (const std::exception& e)
    {
        // errno should still reflect the error from the failing open
        // or write system calls that got us here.
        auto rc = errno;
        instancePath /= "device";
        using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
        report<WriteFailure>(
            xyz::openbmc_project::Control::Device::
                WriteFailure::CALLOUT_ERRNO(rc),
            xyz::openbmc_project::Control::Device::
                WriteFailure::CALLOUT_DEVICE_PATH(
                    fs::canonical(instancePath).c_str()));

        exit(EXIT_FAILURE);
    }

    return value;
}

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<commit_msg>Update call out algorithm for iio hwmon instance<commit_after>/**
 * Copyright © 2016 IBM 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 <cstdlib>
#include <experimental/filesystem>
#include <memory>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <xyz/openbmc_project/Control/Device/error.hpp>
#include <xyz/openbmc_project/Sensor/Device/error.hpp>
#include "sysfs.hpp"
#include "util.hpp"
#include <fstream>

using namespace phosphor::logging;
namespace fs = std::experimental::filesystem;

static constexpr auto ofRoot = "/sys/firmware/devicetree/base";

/**
 * @brief Return the path to the phandle file matching value in io-channels.
 *
 * This function will take two passed in paths.
 * One path is used to find the io-channels file.
 * The other path is used to find the phandle file.
 * The 4 byte phandle value is read from the phandle file(s).
 * The 4 byte phandle value and 4 byte index value is read from io-channels.
 * When a match is found, the path to the matching phandle file is returned.
 *
 * @param[in] iochanneldir - Path to file for getting phandle from io-channels
 * @param[in] phandledir - Path to use for reading from phandle file
 *
 * @return Path to phandle file with value matching that in io-channels
 */
std::string findPhandleMatch(const std::string& iochanneldir,
                             const std::string& phandledir)
{
    for (const auto& ofInst : fs::recursive_directory_iterator(phandledir))
    {
        auto path = ofInst.path();
        if ("phandle" == ofInst.path().filename())
        {
            auto ioChannelsPath = iochanneldir + "/io-channels";
            if (fs::exists(ioChannelsPath))
            {
                auto fullOfPathPhandle = ofInst.path();
                std::ifstream ioChannelsFile(path);
                std::ifstream pHandleFile(fullOfPathPhandle);

                uint32_t ioChannelsValue;
                uint32_t pHandleValue;

                try
                {
                    ioChannelsFile.read(reinterpret_cast<char*>(&ioChannelsValue),
                                        sizeof(ioChannelsValue));
                    pHandleFile.read(reinterpret_cast<char*>(&pHandleValue),
                                     sizeof(pHandleValue));

                    if (ioChannelsValue == pHandleValue)
                    {
                        return ofInst.path();
                    }
                }
                catch (const std::exception& e)
                {
                    log<level::INFO>(e.what());
                    continue;
                }

            }
        }
    }

    return std::string();
}

/**
 * @brief Return the path to use for a call out.
 *
 * If the path does not contain iio-hwmon, assume passed in path is the call
 * out path.
 *
 * @param[in] ofPath - Open firmware path to search for matching phandle value
 *
 * @return Path to use for call out
 */
std::string findCalloutPath(const std::string& ofPath)
{
    static constexpr auto iioHwmonStr = "iio-hwmon";

    if (ofPath.find(iioHwmonStr) != std::string::npos)
    {
        auto matchpath = findPhandleMatch(ofPath, ofRoot);
        auto n = matchpath.rfind('/');
        if (n != std::string::npos)
        {
            return matchpath.substr(0, n);
        }
    }

    return ofPath;
}

std::string findHwmon(const std::string& ofNode)
{
    static constexpr auto hwmonRoot = "/sys/class/hwmon";

    fs::path fullOfPath{ofRoot};
    fullOfPath /= ofNode;

    for (const auto& hwmonInst : fs::directory_iterator(hwmonRoot))
    {
        auto path = hwmonInst.path();
        path /= "of_node";
        if (fs::canonical(path) != fullOfPath)
        {
            // Try to find HWMON instance via phandle values.
            // Used for IIO device drivers.
            auto ofpath = fullOfPath.string();
            auto matchpath = findPhandleMatch(path, ofpath);
            if (!std::string(matchpath).empty())
            {
                return hwmonInst.path();
            }
            else
            {
                continue;
            }
        }

        return hwmonInst.path();
    }

    return std::string();
}

int readSysfsWithCallout(const std::string& root,
                         const std::string& instance,
                         const std::string& type,
                         const std::string& id,
                         const std::string& sensor)
{
    namespace fs = std::experimental::filesystem;

    int value = 0;
    std::ifstream ifs;
    fs::path instancePath{root};
    instancePath /= instance;
    std::string fullPath = make_sysfs_path(instancePath,
                                           type, id, sensor);

    auto callOutPath = findCalloutPath(fs::canonical(instancePath));

    ifs.exceptions(std::ifstream::failbit
                   | std::ifstream::badbit
                   | std::ifstream::eofbit);
    try
    {
        ifs.open(fullPath);
        ifs >> value;
    }
    catch (const std::exception& e)
    {
        // Too many GCC bugs (53984, 66145) to do
        // this the right way...

        // errno should still reflect the error from the failing open
        // or read system calls that got us here.
        auto rc = errno;
        instancePath /= "device";
        using namespace sdbusplus::xyz::openbmc_project::Sensor::Device::Error;
        report<ReadFailure>(
            xyz::openbmc_project::Sensor::Device::
                ReadFailure::CALLOUT_ERRNO(rc),
            xyz::openbmc_project::Sensor::Device::
                ReadFailure::CALLOUT_DEVICE_PATH(
                    fs::canonical(callOutPath).c_str()));

        exit(EXIT_FAILURE);
    }

    return value;
}

uint64_t writeSysfsWithCallout(const uint64_t& value,
                               const std::string& root,
                               const std::string& instance,
                               const std::string& type,
                               const std::string& id,
                               const std::string& sensor)
{
    namespace fs = std::experimental::filesystem;

    std::string valueStr = std::to_string(value);
    std::ofstream ofs;
    fs::path instancePath{root};
    instancePath /= instance;
    std::string fullPath = make_sysfs_path(instancePath,
                                           type, id, sensor);

    auto callOutPath = findCalloutPath(fs::canonical(instancePath));

    ofs.exceptions(std::ofstream::failbit
                   | std::ofstream::badbit
                   | std::ofstream::eofbit);
    try
    {
        ofs.open(fullPath);
        ofs << valueStr;
    }
    catch (const std::exception& e)
    {
        // errno should still reflect the error from the failing open
        // or write system calls that got us here.
        auto rc = errno;
        instancePath /= "device";
        using namespace sdbusplus::xyz::openbmc_project::Control::Device::Error;
        report<WriteFailure>(
            xyz::openbmc_project::Control::Device::
                WriteFailure::CALLOUT_ERRNO(rc),
            xyz::openbmc_project::Control::Device::
                WriteFailure::CALLOUT_DEVICE_PATH(
                    fs::canonical(callOutPath).c_str()));

        exit(EXIT_FAILURE);
    }

    return value;
}

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<|endoftext|>


<commit_before>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/geom.h>
#include <stdio.h>

namespace geos {

bool
CoordinateSequence::hasRepeatedPoints() const
{
	int size=getSize();
	for(int i=1; i<size; i++) {
		if (getAt(i-1)==getAt(i)) {
			return true;
		}
	}
	return false;
}

/*
 * Returns either the given coordinate array if its length is greater than the
 * given amount, or an empty coordinate array.
 */
CoordinateSequence *
CoordinateSequence::atLeastNCoordinatesOrNothing(int n, CoordinateSequence *c)
{
	return c->getSize()>=n?c:DefaultCoordinateSequenceFactory::instance()->create(NULL);
}

bool
CoordinateSequence::hasRepeatedPoints(const CoordinateSequence *cl) {
	int size=(int) cl->getSize();
	for(int i=1;i<size; i++) {
		if (cl->getAt(i-1)==cl->getAt(i)) {
			return true;
		}
	}
	return false;
}

const Coordinate* CoordinateSequence::minCoordinate() const {
	const Coordinate* minCoord=NULL;
	int size=(int) getSize();
	for(int i=0; i<size; i++) {
		if(minCoord==NULL || minCoord->compareTo(getAt(i))>0) {
			minCoord=&getAt(i);
		}
	}
	return minCoord;
}

const Coordinate*
CoordinateSequence::minCoordinate(CoordinateSequence *cl)
{
	const Coordinate* minCoord=NULL;
	int size=(int) cl->getSize();
	for(int i=0;i<size; i++) {
		if(minCoord==NULL || minCoord->compareTo(cl->getAt(i))>0) {
			minCoord=&(cl->getAt(i));
		}
	}
	return minCoord;
}

int
CoordinateSequence::indexOf(const Coordinate *coordinate, const CoordinateSequence *cl)
{
	for (int i=0; i<cl->getSize(); i++) {
		if ((*coordinate)==cl->getAt(i)) {
			return i;
		}
	}
	return -1;
}

void
CoordinateSequence::scroll(CoordinateSequence* cl,const Coordinate* firstCoordinate)
{
	int i, j=0;
	int ind=indexOf(firstCoordinate,cl);
	if (ind<1) return; // not found or already first
	int length=cl->getSize();
	vector<Coordinate> v(length);
	for (i=ind; i<length; i++) {
		v[j++]=cl->getAt(i);
	}
	for (i=0; i<ind; i++) {
		v[j++]=cl->getAt(i);
	}
	cl->setPoints(v);
}

void CoordinateSequence::reverse(CoordinateSequence *cl){
	int last=cl->getSize()-1;
	int mid=last/2;
	for(int i=0;i<=mid;i++) {
		const Coordinate tmp=cl->getAt(i);
		cl->setAt(cl->getAt(last-i),i);
		cl->setAt(tmp,last-i);
	}
}

bool CoordinateSequence::equals(CoordinateSequence *cl1,CoordinateSequence *cl2){
	if (cl1==cl2) return true;
	if (cl1==NULL||cl2==NULL) return false;
	if (cl1->getSize()!=cl2->getSize()) return false;
	for (int i = 0; i<cl1->getSize(); i++) {
		if (!(cl1->getAt(i)==cl2->getAt(i))) return false;
	}
	return true;
}

/** Add an array of coordinates
* @param vc The coordinates
* @param allowRepeated if set to false, repeated coordinates are collapsed
* @return true (as by general collection contract)
*/
void CoordinateSequence::add(const vector<Coordinate>* vc,bool allowRepeated) {
	for(int i=0;i<(int)vc->size();i++) {
		add((*vc)[i],allowRepeated);
	}
}

/** Add a coordinate
* @param c The coordinate to add
* @param allowRepeated if set to false, repeated coordinates are collapsed
* @return true (as by general collection contract)
*/
void CoordinateSequence::add(const Coordinate& c,bool allowRepeated) {
	if (!allowRepeated) {
		if (getSize()>=1) {
			const Coordinate& last=getAt(getSize()-1);
			if (last.equals2D(c)) return;
		}
	}
	add(c);
}

/* Here for backward compatibility */
void
CoordinateSequence::add(CoordinateSequence *cl,bool allowRepeated,bool direction)
{
	add((const CoordinateSequence *)cl,allowRepeated,direction);
}

/**
 * Add an array of coordinates
 * @param cl The coordinates
 * @param allowRepeated if set to false, repeated coordinates are collapsed
 * @param direction if false, the array is added in reverse order
 * @return true (as by general collection contract)
 */
void
CoordinateSequence::add(const CoordinateSequence *cl,bool allowRepeated,bool direction)
{
	if (direction) {
		for (int i = 0; i < cl->getSize(); i++) {
			add(cl->getAt(i), allowRepeated);
		}
	} else {
		for (int j =cl->getSize()-1;j>=0;j--) {
			add(cl->getAt(j), allowRepeated);
		}
	}
}

/**
 * This function allocates space for a CoordinateSequence object
 * being a copy of the input once with consecutive equal points
 * removed.
 */
CoordinateSequence*
CoordinateSequence::removeRepeatedPoints(const CoordinateSequence *cl)
{
	CoordinateSequence* ret=DefaultCoordinateSequenceFactory::instance()->create(NULL);
	const vector<Coordinate> *v=cl->toVector();
	ret->add(v,false);
	//delete v;
	return ret;
}

} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.6  2004/12/03 22:52:56  strk
 * enforced const return of CoordinateSequence::toVector() method to derivate classes.
 *
 * Revision 1.5  2004/11/04 19:08:06  strk
 * Cleanups, initializers list, profiling.
 *
 * Revision 1.4  2004/10/13 10:03:02  strk
 * Added missing linemerge and polygonize operation.
 * Bug fixes and leaks removal from the newly added modules and
 * planargraph (used by them).
 * Some comments and indentation changes.
 *
 * Revision 1.3  2004/09/23 21:36:22  strk
 * Fixed a bug in ::reverse (thanks to Elliott Edwards)
 *
 * Revision 1.2  2004/07/21 09:55:24  strk
 * CoordinateSequence::atLeastNCoordinatesOrNothing definition fix.
 * Documentation fixes.
 *
 * Revision 1.1  2004/07/08 19:38:56  strk
 * renamed from *List* equivalents
 *
 **********************************************************************/

<commit_msg>more profiling label<commit_after>/**********************************************************************
 * $Id$
 *
 * GEOS - Geometry Engine Open Source
 * http://geos.refractions.net
 *
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
 *
 * This is free software; you can redistribute and/or modify it under
 * the terms of the GNU Lesser General Public Licence as published
 * by the Free Software Foundation.
 * See the COPYING file for more information.
 *
 **********************************************************************/

#include <geos/geom.h>
#include <geos/profiler.h>
#include <stdio.h>

namespace geos {

#if PROFILE
static Profiler *profiler = Profiler::instance();
#endif

bool
CoordinateSequence::hasRepeatedPoints() const
{
	int size=getSize();
	for(int i=1; i<size; i++) {
		if (getAt(i-1)==getAt(i)) {
			return true;
		}
	}
	return false;
}

/*
 * Returns either the given coordinate array if its length is greater than the
 * given amount, or an empty coordinate array.
 */
CoordinateSequence *
CoordinateSequence::atLeastNCoordinatesOrNothing(int n, CoordinateSequence *c)
{
	return c->getSize()>=n?c:DefaultCoordinateSequenceFactory::instance()->create(NULL);
}

bool
CoordinateSequence::hasRepeatedPoints(const CoordinateSequence *cl) {
	int size=(int) cl->getSize();
	for(int i=1;i<size; i++) {
		if (cl->getAt(i-1)==cl->getAt(i)) {
			return true;
		}
	}
	return false;
}

const Coordinate* CoordinateSequence::minCoordinate() const {
	const Coordinate* minCoord=NULL;
	int size=(int) getSize();
	for(int i=0; i<size; i++) {
		if(minCoord==NULL || minCoord->compareTo(getAt(i))>0) {
			minCoord=&getAt(i);
		}
	}
	return minCoord;
}

const Coordinate*
CoordinateSequence::minCoordinate(CoordinateSequence *cl)
{
	const Coordinate* minCoord=NULL;
	int size=(int) cl->getSize();
	for(int i=0;i<size; i++) {
		if(minCoord==NULL || minCoord->compareTo(cl->getAt(i))>0) {
			minCoord=&(cl->getAt(i));
		}
	}
	return minCoord;
}

int
CoordinateSequence::indexOf(const Coordinate *coordinate, const CoordinateSequence *cl)
{
	for (int i=0; i<cl->getSize(); i++) {
		if ((*coordinate)==cl->getAt(i)) {
			return i;
		}
	}
	return -1;
}

void
CoordinateSequence::scroll(CoordinateSequence* cl,const Coordinate* firstCoordinate)
{
	int i, j=0;
	int ind=indexOf(firstCoordinate,cl);
	if (ind<1) return; // not found or already first
	int length=cl->getSize();
	vector<Coordinate> v(length);
	for (i=ind; i<length; i++) {
		v[j++]=cl->getAt(i);
	}
	for (i=0; i<ind; i++) {
		v[j++]=cl->getAt(i);
	}
	cl->setPoints(v);
}

void CoordinateSequence::reverse(CoordinateSequence *cl){
	int last=cl->getSize()-1;
	int mid=last/2;
	for(int i=0;i<=mid;i++) {
		const Coordinate tmp=cl->getAt(i);
		cl->setAt(cl->getAt(last-i),i);
		cl->setAt(tmp,last-i);
	}
}

bool CoordinateSequence::equals(CoordinateSequence *cl1,CoordinateSequence *cl2){
	if (cl1==cl2) return true;
	if (cl1==NULL||cl2==NULL) return false;
	if (cl1->getSize()!=cl2->getSize()) return false;
	for (int i = 0; i<cl1->getSize(); i++) {
		if (!(cl1->getAt(i)==cl2->getAt(i))) return false;
	}
	return true;
}

/** Add an array of coordinates
* @param vc The coordinates
* @param allowRepeated if set to false, repeated coordinates are collapsed
* @return true (as by general collection contract)
*/
void CoordinateSequence::add(const vector<Coordinate>* vc,bool allowRepeated) {
	for(int i=0;i<(int)vc->size();i++) {
		add((*vc)[i],allowRepeated);
	}
}

/** Add a coordinate
* @param c The coordinate to add
* @param allowRepeated if set to false, repeated coordinates are collapsed
* @return true (as by general collection contract)
*/
void CoordinateSequence::add(const Coordinate& c,bool allowRepeated) {
	if (!allowRepeated) {
		if (getSize()>=1) {
			const Coordinate& last=getAt(getSize()-1);
			if (last.equals2D(c)) return;
		}
	}
	add(c);
}

/* Here for backward compatibility */
void
CoordinateSequence::add(CoordinateSequence *cl,bool allowRepeated,bool direction)
{
	add((const CoordinateSequence *)cl,allowRepeated,direction);
}

/**
 * Add an array of coordinates
 * @param cl The coordinates
 * @param allowRepeated if set to false, repeated coordinates are collapsed
 * @param direction if false, the array is added in reverse order
 * @return true (as by general collection contract)
 */
void
CoordinateSequence::add(const CoordinateSequence *cl,bool allowRepeated,bool direction)
{
	if (direction) {
		for (int i = 0; i < cl->getSize(); i++) {
			add(cl->getAt(i), allowRepeated);
		}
	} else {
		for (int j =cl->getSize()-1;j>=0;j--) {
			add(cl->getAt(j), allowRepeated);
		}
	}
}

/**
 * This function allocates space for a CoordinateSequence object
 * being a copy of the input once with consecutive equal points
 * removed.
 */
CoordinateSequence*
CoordinateSequence::removeRepeatedPoints(const CoordinateSequence *cl)
{
#if PROFILE
	static Profile *prof= profiler->get("CoordinateSequence::removeRepeatedPoints()");
	prof->start();
#endif
	CoordinateSequence* ret=DefaultCoordinateSequenceFactory::instance()->create(NULL);
	const vector<Coordinate> *v=cl->toVector();
	ret->add(v,false);
	//delete v;
#if PROFILE
	prof->stop();
#endif
	return ret;
}

} // namespace geos

/**********************************************************************
 * $Log$
 * Revision 1.7  2005/02/03 09:17:07  strk
 * more profiling label
 *
 * Revision 1.6  2004/12/03 22:52:56  strk
 * enforced const return of CoordinateSequence::toVector() method to derivate classes.
 *
 * Revision 1.5  2004/11/04 19:08:06  strk
 * Cleanups, initializers list, profiling.
 *
 * Revision 1.4  2004/10/13 10:03:02  strk
 * Added missing linemerge and polygonize operation.
 * Bug fixes and leaks removal from the newly added modules and
 * planargraph (used by them).
 * Some comments and indentation changes.
 *
 * Revision 1.3  2004/09/23 21:36:22  strk
 * Fixed a bug in ::reverse (thanks to Elliott Edwards)
 *
 * Revision 1.2  2004/07/21 09:55:24  strk
 * CoordinateSequence::atLeastNCoordinatesOrNothing definition fix.
 * Documentation fixes.
 *
 * Revision 1.1  2004/07/08 19:38:56  strk
 * renamed from *List* equivalents
 *
 **********************************************************************/

<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013-2016, SimQuest Solutions Inc.
//
// 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 "SurgSim/Math/OdeState.h"

#include "SurgSim/Framework/Assert.h"
#include "SurgSim/Math/Valid.h"

namespace SurgSim
{

namespace Math
{

OdeState::OdeState() : m_numDofPerNode(0u), m_numNodes(0u)
{
}

OdeState::~OdeState()
{
}

bool OdeState::operator ==(const OdeState& state) const
{
	return m_x == state.m_x && m_v == state.m_v && m_boundaryConditionsPerDof == state.m_boundaryConditionsPerDof &&
		m_boundaryConditionsStaticDof == state.m_boundaryConditionsStaticDof;
}

bool OdeState::operator !=(const OdeState& state) const
{
	return !((*this) == state);
}

void OdeState::reset()
{
	m_x.setZero();
	m_v.setZero();
	m_boundaryConditionsPerDof.setConstant(false);
	m_boundaryConditionsAsDofIds.clear();
	m_boundaryConditionsStaticDof.clear();
}

void OdeState::setNumDof(size_t numDofPerNode, size_t numNodes)
{
	const size_t numDof = numDofPerNode * numNodes;

	m_numDofPerNode = numDofPerNode;
	m_numNodes = numNodes;

	m_x.resize(numDof);
	m_v.resize(numDof);
	m_boundaryConditionsPerDof.resize(numDof);

	// Zero-out everything
	reset();
}

size_t OdeState::getNumDof() const
{
	const size_t numDof = m_numDofPerNode * m_numNodes;

	SURGSIM_ASSERT(m_x.size() == m_v.size() && m_x.size() == m_boundaryConditionsPerDof.size() && m_x.size() >= 0
				   && static_cast<size_t>(m_x.size()) == numDof);

	return numDof;
}

size_t OdeState::getNumNodes() const
{
	return m_numNodes;
}

SurgSim::Math::Vector& OdeState::getPositions()
{
	return m_x;
}

const SurgSim::Math::Vector& OdeState::getPositions() const
{
	return m_x;
}

const SurgSim::Math::Vector3d OdeState::getPosition(size_t nodeId) const
{
	return SurgSim::Math::getSubVector(m_x, nodeId, m_numDofPerNode).segment(0, 3);
}

SurgSim::Math::Vector& OdeState::getVelocities()
{
	return m_v;
}

const SurgSim::Math::Vector& OdeState::getVelocities() const
{
	return m_v;
}

const SurgSim::Math::Vector3d OdeState::getVelocity(size_t nodeId) const
{
	return SurgSim::Math::getSubVector(m_v, nodeId, m_numDofPerNode).segment(0, 3);
}

void OdeState::addBoundaryCondition(size_t nodeId)
{
	SURGSIM_ASSERT(m_numDofPerNode != 0u) <<
										  "Number of dof per node = 0. Make sure to call setNumDof() " <<
										  "prior to adding boundary conditions.";

	for (size_t nodeDofId = 0; nodeDofId < m_numDofPerNode; ++nodeDofId)
	{
		addBoundaryCondition(nodeId, nodeDofId);
	}
}

void OdeState::addBoundaryCondition(size_t nodeId, size_t nodeDofId)
{
	SURGSIM_ASSERT(m_numDofPerNode != 0u) <<
										  "Number of dof per node = 0. Make sure to call setNumDof() " <<
										  "prior to adding boundary conditions.";
	SURGSIM_ASSERT(nodeId < m_numNodes) << "Invalid nodeId " << nodeId << " number of nodes is " << m_numNodes;
	SURGSIM_ASSERT(nodeDofId < m_numDofPerNode) <<
			"Invalid nodeDofId " << nodeDofId << " number of dof per node is " << m_numDofPerNode;

	size_t globalDofId = nodeId * m_numDofPerNode + nodeDofId;
	if (! m_boundaryConditionsPerDof[globalDofId])
	{
		m_boundaryConditionsPerDof[globalDofId] = true;
		m_boundaryConditionsAsDofIds.push_back(globalDofId);
	}
}

size_t OdeState::getNumBoundaryConditions() const
{
	return m_boundaryConditionsAsDofIds.size();
}

const std::vector<size_t>& OdeState::getBoundaryConditions() const
{
	return m_boundaryConditionsAsDofIds;
}

bool OdeState::isBoundaryCondition(size_t dof) const
{
	return m_boundaryConditionsPerDof[dof];
}

Vector* OdeState::applyBoundaryConditionsToVector(Vector* vector) const
{
	SURGSIM_ASSERT(vector != nullptr && vector->size() >= 0 && static_cast<size_t>(vector->size()) == getNumDof())
			<< "Invalid vector to apply boundary conditions on";

	const size_t numDofPerNode = getNumDof() / getNumNodes();
	const size_t N = numDofPerNode * (getNumNodes() - 2);
	for (auto it = getBoundaryConditions().cbegin();
		 it != getBoundaryConditions().cend();
		 ++it)
	{
		//if (*it == N)
		//{
		//	(*vector)[*it] = -0.0001;
		//	std::cout << "(*vector)["<<*it<<"] = -0.01;" << std::endl;
		//}
		//else if (*it == N + 1)
		//{
		//	(*vector)[*it] = -0.00001;
		//}
		//else if (*it == N + 2)
		//{
		//	(*vector)[*it] = -0.0000003;
		//}
		//else
		{
			(*vector)[*it] = 0.0;
		}
	}

	return vector;
}

void OdeState::applyBoundaryConditionsToMatrix(Matrix* matrix, bool hasCompliance) const
{
	SURGSIM_ASSERT(matrix != nullptr && static_cast<size_t>(matrix->rows()) == getNumDof()
				   && static_cast<size_t>(matrix->cols()) == getNumDof())
			<< "Invalid matrix to apply boundary conditions on";

	double complianceValue  = 0.0;

	if (hasCompliance)
	{
		complianceValue = 1.0;
	}

	for (auto it = getBoundaryConditions().cbegin();
		 it != getBoundaryConditions().cend();
		 ++it)
	{
		(*matrix).middleRows(*it, 1).setZero();
		(*matrix).middleCols(*it, 1).setZero();
		(*matrix)(*it, *it) = complianceValue;
	}
}

void OdeState::applyBoundaryConditionsToMatrix(SparseMatrix* matrix, bool hasCompliance) const
{
	SURGSIM_ASSERT(matrix != nullptr && static_cast<size_t>(matrix->rows()) == getNumDof()
				   && static_cast<size_t>(matrix->cols()) == getNumDof())
			<< "Invalid matrix to apply boundary conditions on";

	double complianceValue  = 0.0;

	if (hasCompliance)
	{
		complianceValue = 1.0;
	}

	for (auto it = getBoundaryConditions().cbegin();
		 it != getBoundaryConditions().cend();
		 ++it)
	{
		Math::zeroRow((*it), matrix);
		Math::zeroColumn(static_cast<SparseMatrix::Index>((*it)), matrix);
		(*matrix).coeffRef(static_cast<SparseMatrix::Index>(*it),
						   static_cast<SparseMatrix::Index>(*it)) = complianceValue;
	}
}

void OdeState::addBoundaryConditionStaticDof(size_t nodeId, double value)
{
	SURGSIM_ASSERT(m_numDofPerNode != 0u) <<
		"Number of dof per node = 0. Make sure to call setNumDof() " <<
		"prior to adding boundary conditions.";
	SURGSIM_ASSERT(nodeId < m_numNodes) << "Invalid nodeId " << nodeId << " number of nodes is " << m_numNodes;

	m_boundaryConditionsStaticDof.push_back(std::make_pair(nodeId, value));
}

size_t OdeState::getNumBoundaryConditionsStaticDof() const
{
	return m_boundaryConditionsStaticDof.size();
}

const std::vector<std::pair<size_t, double>>& OdeState::getBoundaryConditionsStaticDof() const
{
	return m_boundaryConditionsStaticDof;
}

void OdeState::setBoundaryConditionStaticDof(size_t nodeId, double value)
{
	auto bc = std::find_if(m_boundaryConditionsStaticDof.begin(), m_boundaryConditionsStaticDof.end(), [&nodeId](std::pair<size_t, double>& pair) { return pair.first == nodeId;  });
	if (bc != m_boundaryConditionsStaticDof.end())
	{
		bc->second = value;
	}
}

bool OdeState::isValid() const
{
	using SurgSim::Math::isValid;

	/// http://steve.hollasch.net/cgindex/coding/ieeefloat.html
	/// We use the IEEE754 standard stipulating that any arithmetic operation with a NaN operand will produce NaN
	/// and any sum of +-INF with a finite number or +-INF will produce +-INF.
	/// Therefore, testing if a vector contains only finite numbers can be achieve easily by summing all the values
	/// and testing if the result is a finite number or not.
	return isValid(getPositions().sum()) && isValid(getVelocities().sum());
}

OdeState OdeState::interpolate(const OdeState& other, double t) const
{
	auto result = OdeState(*this);
	if (t != 0)
	{
		result.m_v += (other.m_v - m_v) * t;
		result.m_x += (other.m_x - m_x) * t;
	}
	return result;
}

}; // namespace Math

}; // namespace SurgSim
<commit_msg>Remove commented code.<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013-2016, SimQuest Solutions Inc.
//
// 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 "SurgSim/Math/OdeState.h"

#include "SurgSim/Framework/Assert.h"
#include "SurgSim/Math/Valid.h"

namespace SurgSim
{

namespace Math
{

OdeState::OdeState() : m_numDofPerNode(0u), m_numNodes(0u)
{
}

OdeState::~OdeState()
{
}

bool OdeState::operator ==(const OdeState& state) const
{
	return m_x == state.m_x && m_v == state.m_v && m_boundaryConditionsPerDof == state.m_boundaryConditionsPerDof &&
		m_boundaryConditionsStaticDof == state.m_boundaryConditionsStaticDof;
}

bool OdeState::operator !=(const OdeState& state) const
{
	return !((*this) == state);
}

void OdeState::reset()
{
	m_x.setZero();
	m_v.setZero();
	m_boundaryConditionsPerDof.setConstant(false);
	m_boundaryConditionsAsDofIds.clear();
	m_boundaryConditionsStaticDof.clear();
}

void OdeState::setNumDof(size_t numDofPerNode, size_t numNodes)
{
	const size_t numDof = numDofPerNode * numNodes;

	m_numDofPerNode = numDofPerNode;
	m_numNodes = numNodes;

	m_x.resize(numDof);
	m_v.resize(numDof);
	m_boundaryConditionsPerDof.resize(numDof);

	// Zero-out everything
	reset();
}

size_t OdeState::getNumDof() const
{
	const size_t numDof = m_numDofPerNode * m_numNodes;

	SURGSIM_ASSERT(m_x.size() == m_v.size() && m_x.size() == m_boundaryConditionsPerDof.size() && m_x.size() >= 0
				   && static_cast<size_t>(m_x.size()) == numDof);

	return numDof;
}

size_t OdeState::getNumNodes() const
{
	return m_numNodes;
}

SurgSim::Math::Vector& OdeState::getPositions()
{
	return m_x;
}

const SurgSim::Math::Vector& OdeState::getPositions() const
{
	return m_x;
}

const SurgSim::Math::Vector3d OdeState::getPosition(size_t nodeId) const
{
	return SurgSim::Math::getSubVector(m_x, nodeId, m_numDofPerNode).segment(0, 3);
}

SurgSim::Math::Vector& OdeState::getVelocities()
{
	return m_v;
}

const SurgSim::Math::Vector& OdeState::getVelocities() const
{
	return m_v;
}

const SurgSim::Math::Vector3d OdeState::getVelocity(size_t nodeId) const
{
	return SurgSim::Math::getSubVector(m_v, nodeId, m_numDofPerNode).segment(0, 3);
}

void OdeState::addBoundaryCondition(size_t nodeId)
{
	SURGSIM_ASSERT(m_numDofPerNode != 0u) <<
										  "Number of dof per node = 0. Make sure to call setNumDof() " <<
										  "prior to adding boundary conditions.";

	for (size_t nodeDofId = 0; nodeDofId < m_numDofPerNode; ++nodeDofId)
	{
		addBoundaryCondition(nodeId, nodeDofId);
	}
}

void OdeState::addBoundaryCondition(size_t nodeId, size_t nodeDofId)
{
	SURGSIM_ASSERT(m_numDofPerNode != 0u) <<
										  "Number of dof per node = 0. Make sure to call setNumDof() " <<
										  "prior to adding boundary conditions.";
	SURGSIM_ASSERT(nodeId < m_numNodes) << "Invalid nodeId " << nodeId << " number of nodes is " << m_numNodes;
	SURGSIM_ASSERT(nodeDofId < m_numDofPerNode) <<
			"Invalid nodeDofId " << nodeDofId << " number of dof per node is " << m_numDofPerNode;

	size_t globalDofId = nodeId * m_numDofPerNode + nodeDofId;
	if (! m_boundaryConditionsPerDof[globalDofId])
	{
		m_boundaryConditionsPerDof[globalDofId] = true;
		m_boundaryConditionsAsDofIds.push_back(globalDofId);
	}
}

size_t OdeState::getNumBoundaryConditions() const
{
	return m_boundaryConditionsAsDofIds.size();
}

const std::vector<size_t>& OdeState::getBoundaryConditions() const
{
	return m_boundaryConditionsAsDofIds;
}

bool OdeState::isBoundaryCondition(size_t dof) const
{
	return m_boundaryConditionsPerDof[dof];
}

Vector* OdeState::applyBoundaryConditionsToVector(Vector* vector) const
{
	SURGSIM_ASSERT(vector != nullptr && vector->size() >= 0 && static_cast<size_t>(vector->size()) == getNumDof())
			<< "Invalid vector to apply boundary conditions on";

	const size_t numDofPerNode = getNumDof() / getNumNodes();
	const size_t N = numDofPerNode * (getNumNodes() - 2);
	for (auto it = getBoundaryConditions().cbegin();
		 it != getBoundaryConditions().cend();
		 ++it)
	{
		(*vector)[*it] = 0.0;
	}

	return vector;
}

void OdeState::applyBoundaryConditionsToMatrix(Matrix* matrix, bool hasCompliance) const
{
	SURGSIM_ASSERT(matrix != nullptr && static_cast<size_t>(matrix->rows()) == getNumDof()
				   && static_cast<size_t>(matrix->cols()) == getNumDof())
			<< "Invalid matrix to apply boundary conditions on";

	double complianceValue  = 0.0;

	if (hasCompliance)
	{
		complianceValue = 1.0;
	}

	for (auto it = getBoundaryConditions().cbegin();
		 it != getBoundaryConditions().cend();
		 ++it)
	{
		(*matrix).middleRows(*it, 1).setZero();
		(*matrix).middleCols(*it, 1).setZero();
		(*matrix)(*it, *it) = complianceValue;
	}
}

void OdeState::applyBoundaryConditionsToMatrix(SparseMatrix* matrix, bool hasCompliance) const
{
	SURGSIM_ASSERT(matrix != nullptr && static_cast<size_t>(matrix->rows()) == getNumDof()
				   && static_cast<size_t>(matrix->cols()) == getNumDof())
			<< "Invalid matrix to apply boundary conditions on";

	double complianceValue  = 0.0;

	if (hasCompliance)
	{
		complianceValue = 1.0;
	}

	for (auto it = getBoundaryConditions().cbegin();
		 it != getBoundaryConditions().cend();
		 ++it)
	{
		Math::zeroRow((*it), matrix);
		Math::zeroColumn(static_cast<SparseMatrix::Index>((*it)), matrix);
		(*matrix).coeffRef(static_cast<SparseMatrix::Index>(*it),
						   static_cast<SparseMatrix::Index>(*it)) = complianceValue;
	}
}

void OdeState::addBoundaryConditionStaticDof(size_t nodeId, double value)
{
	SURGSIM_ASSERT(m_numDofPerNode != 0u) <<
		"Number of dof per node = 0. Make sure to call setNumDof() " <<
		"prior to adding boundary conditions.";
	SURGSIM_ASSERT(nodeId < m_numNodes) << "Invalid nodeId " << nodeId << " number of nodes is " << m_numNodes;

	m_boundaryConditionsStaticDof.push_back(std::make_pair(nodeId, value));
}

size_t OdeState::getNumBoundaryConditionsStaticDof() const
{
	return m_boundaryConditionsStaticDof.size();
}

const std::vector<std::pair<size_t, double>>& OdeState::getBoundaryConditionsStaticDof() const
{
	return m_boundaryConditionsStaticDof;
}

void OdeState::setBoundaryConditionStaticDof(size_t nodeId, double value)
{
	auto bc = std::find_if(m_boundaryConditionsStaticDof.begin(), m_boundaryConditionsStaticDof.end(), [&nodeId](std::pair<size_t, double>& pair) { return pair.first == nodeId;  });
	if (bc != m_boundaryConditionsStaticDof.end())
	{
		bc->second = value;
	}
}

bool OdeState::isValid() const
{
	using SurgSim::Math::isValid;

	/// http://steve.hollasch.net/cgindex/coding/ieeefloat.html
	/// We use the IEEE754 standard stipulating that any arithmetic operation with a NaN operand will produce NaN
	/// and any sum of +-INF with a finite number or +-INF will produce +-INF.
	/// Therefore, testing if a vector contains only finite numbers can be achieve easily by summing all the values
	/// and testing if the result is a finite number or not.
	return isValid(getPositions().sum()) && isValid(getVelocities().sum());
}

OdeState OdeState::interpolate(const OdeState& other, double t) const
{
	auto result = OdeState(*this);
	if (t != 0)
	{
		result.m_v += (other.m_v - m_v) * t;
		result.m_x += (other.m_x - m_x) * t;
	}
	return result;
}

}; // namespace Math

}; // namespace SurgSim
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PlotterBase.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: ihi $ $Date: 2006-11-14 15:35:03 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CHART2_PLOTTERBASE_HXX
#define _CHART2_PLOTTERBASE_HXX

#ifndef _COM_SUN_STAR_DRAWING_HOMOGENMATRIX_HPP_
#include <com/sun/star/drawing/HomogenMatrix.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_XSHAPES_HPP_
#include <com/sun/star/drawing/XShapes.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_POSITION3D_HPP_
#include <com/sun/star/drawing/Position3D.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
/*
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
*/

//----
#include <vector>

//---- chart2
#ifndef _COM_SUN_STAR_CHART2_EXPLICITSCALEDATA_HPP_
#include <com/sun/star/chart2/ExplicitScaleData.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XTRANSFORMATION_HPP_
#include <com/sun/star/chart2/XTransformation.hpp>
#endif
/*
#ifndef _COM_SUN_STAR_CHART2_XPLOTTER_HPP_
#include <com/sun/star/chart2/XPlotter.hpp>
#endif
*/

//----
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

//#ifndef _B3D_HMATRIX_HXX
//#include <goodies/hmatrix.hxx>
//#endif

//.............................................................................
namespace chart
{
//.............................................................................

class ShapeFactory;
class PlottingPositionHelper;

class PlotterBase
{
public:
    PlotterBase( sal_Int32 nDimension );
    virtual ~PlotterBase();

    // ___chart2::XPlotter___
    virtual void SAL_CALL init(
          const ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::XShapes >& xLogicTarget
        , const ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::XShapes >& xFinalTarget
        , const ::com::sun::star::uno::Reference<
                ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
                throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL setScales(
          const ::com::sun::star::uno::Sequence<
            ::com::sun::star::chart2::ExplicitScaleData >& rScales )
                throw (::com::sun::star::uno::RuntimeException);

    void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix );

    virtual void SAL_CALL createShapes() = 0;

    /*
    virtual ::rtl::OUString SAL_CALL getCoordinateSystemTypeID(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setTransformation( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >& xTransformationToLogicTarget, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >& xTransformationToFinalPage ) throw (::com::sun::star::uno::RuntimeException);
    */

    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
private: //methods
    //no default constructor
    PlotterBase();

protected: //methods
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
        createGroupShape( const ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::XShapes >& xTarget
                , ::rtl::OUString rName=::rtl::OUString() );

protected: //member
    ::com::sun::star::uno::Reference<
                    ::com::sun::star::drawing::XShapes >                m_xLogicTarget;
    ::com::sun::star::uno::Reference<
                    ::com::sun::star::drawing::XShapes >                m_xFinalTarget;
    ::com::sun::star::uno::Reference<
                    ::com::sun::star::lang::XMultiServiceFactory>       m_xShapeFactory;
    ShapeFactory*                                                       m_pShapeFactory;
    //::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>          m_xCC;

    sal_Int32                                           m_nDimension;
    // needs to be created and deleted by the derived class
    PlottingPositionHelper*                             m_pPosHelper;
};
//.............................................................................
} //namespace chart
//.............................................................................
#endif
<commit_msg>INTEGRATION: CWS chart2mst3 (1.10.4); FILE MERGED 2006/11/22 17:26:06 iha 1.10.4.6: RESYNC: (1.11-1.12); FILE MERGED 2006/08/22 19:07:31 iha 1.10.4.5: correct y axis for net charts: show labels + take space for labels into account for diagram size 2005/12/21 21:29:38 iha 1.10.4.4: remove identifiers from model objects and create an index based CID protocol instead for selection purposes 2005/10/07 12:20:48 bm 1.10.4.3: RESYNC: (1.10-1.11); FILE MERGED 2004/03/22 19:31:41 iha 1.10.4.2: transport information bSwapXAndYAxis over method setScales not constructor 2004/03/01 18:13:51 iha 1.10.4.1: added method isValidPosition()<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: PlotterBase.hxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 19:19:33 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CHART2_PLOTTERBASE_HXX
#define _CHART2_PLOTTERBASE_HXX

#ifndef _COM_SUN_STAR_DRAWING_HOMOGENMATRIX_HPP_
#include <com/sun/star/drawing/HomogenMatrix.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_XSHAPES_HPP_
#include <com/sun/star/drawing/XShapes.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_XCOMPONENTCONTEXT_HPP_
#include <com/sun/star/uno/XComponentContext.hpp>
#endif
#ifndef _COM_SUN_STAR_DRAWING_POSITION3D_HPP_
#include <com/sun/star/drawing/Position3D.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
#include <com/sun/star/beans/XPropertySet.hpp>
#endif
/*
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
*/

//----
#include <vector>

//---- chart2
#ifndef _COM_SUN_STAR_CHART2_EXPLICITSCALEDATA_HPP_
#include <com/sun/star/chart2/ExplicitScaleData.hpp>
#endif
#ifndef _COM_SUN_STAR_CHART2_XTRANSFORMATION_HPP_
#include <com/sun/star/chart2/XTransformation.hpp>
#endif
/*
#ifndef _COM_SUN_STAR_CHART2_XPLOTTER_HPP_
#include <com/sun/star/chart2/XPlotter.hpp>
#endif
*/

//----
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif

//.............................................................................
namespace chart
{
//.............................................................................

class ShapeFactory;
class PlottingPositionHelper;

class PlotterBase
{
public:
    PlotterBase( sal_Int32 nDimension );
    virtual ~PlotterBase();

    // ___chart2::XPlotter___
    virtual void SAL_CALL initPlotter(
          const ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::XShapes >& xLogicTarget
        , const ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::XShapes >& xFinalTarget
        , const ::com::sun::star::uno::Reference<
                ::com::sun::star::lang::XMultiServiceFactory >& xFactory
        , const rtl::OUString& rCID
                ) throw (::com::sun::star::uno::RuntimeException );

    virtual void SAL_CALL setScales(
          const ::com::sun::star::uno::Sequence<
            ::com::sun::star::chart2::ExplicitScaleData >& rScales
            , sal_Bool bSwapXAndYAxis )
                throw (::com::sun::star::uno::RuntimeException);

    virtual void setTransformationSceneToScreen( const ::com::sun::star::drawing::HomogenMatrix& rMatrix );

    virtual void SAL_CALL createShapes() = 0;

    static bool isValidPosition( const ::com::sun::star::drawing::Position3D& rPos );
    /*
    virtual ::rtl::OUString SAL_CALL getCoordinateSystemTypeID(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setTransformation( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >& xTransformationToLogicTarget, const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTransformation >& xTransformationToFinalPage ) throw (::com::sun::star::uno::RuntimeException);
    */

    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
    //-------------------------------------------------------------------------
private: //methods
    //no default constructor
    PlotterBase();

protected: //methods
    ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >
        createGroupShape( const ::com::sun::star::uno::Reference<
                ::com::sun::star::drawing::XShapes >& xTarget
                , ::rtl::OUString rName=::rtl::OUString() );

protected: //member
    ::com::sun::star::uno::Reference<
                    ::com::sun::star::drawing::XShapes >                m_xLogicTarget;
    ::com::sun::star::uno::Reference<
                    ::com::sun::star::drawing::XShapes >                m_xFinalTarget;
    ::com::sun::star::uno::Reference<
                    ::com::sun::star::lang::XMultiServiceFactory>       m_xShapeFactory;
    ShapeFactory*                                                       m_pShapeFactory;
    //::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>          m_xCC;

    rtl::OUString   m_aCID;

    sal_Int32                                           m_nDimension;
    // needs to be created and deleted by the derived class
    PlottingPositionHelper*                             m_pPosHelper;
};
//.............................................................................
} //namespace chart
//.............................................................................
#endif
<|endoftext|>


<commit_before> /*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: accframebase.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:48:24 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#pragma hdrstop

#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_
#include <unotools/accessiblestatesethelper.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_ //autogen
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif

#ifndef _FRMFMT_HXX
#include <frmfmt.hxx>
#endif
#ifndef _NDNOTXT_HXX
#include <ndnotxt.hxx>
#endif
#ifndef _FLYFRM_HXX
#include <flyfrm.hxx>
#endif
#ifndef _CNTFRM_HXX
#include <cntfrm.hxx>
#endif
#ifndef _FMTCNTNT_HXX
#include <fmtcntnt.hxx>
#endif
#ifndef _NDINDEX_HXX
#include <ndindex.hxx>
#endif
#ifndef _FESH_HXX
#include "fesh.hxx"
#endif
#ifndef _HINTS_HXX
#include <hints.hxx>
#endif

#ifndef _ACCMAP_HXX
#include "accmap.hxx"
#endif
#ifndef _ACCFRAMEBASE_HXX
#include "accframebase.hxx"
#endif

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::accessibility;
using namespace ::rtl;

sal_Bool SwAccessibleFrameBase::IsSelected()
{
    sal_Bool bRet = sal_False;

    DBG_ASSERT( GetMap(), "no map?" );
    const ViewShell *pVSh = GetMap()->GetShell();
    DBG_ASSERT( pVSh, "no shell?" );
    if( pVSh->ISA( SwFEShell ) )
    {
        const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
        const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
        if( pFlyFrm == GetFrm() )
            bRet = sal_True;
    }

    return bRet;
}

void SwAccessibleFrameBase::GetStates(
        ::utl::AccessibleStateSetHelper& rStateSet )
{
    SwAccessibleContext::GetStates( rStateSet );

    const ViewShell *pVSh = GetMap()->GetShell();
    DBG_ASSERT( pVSh, "no shell?" );
    sal_Bool bSelectable =  pVSh->ISA( SwFEShell );

    // SELECTABLE
    if( bSelectable )
        rStateSet.AddState( AccessibleStateType::SELECTABLE );

    // FOCUSABLE
    if( bSelectable )
        rStateSet.AddState( AccessibleStateType::FOCUSABLE );

    // SELECTED and FOCUSED
    if( IsSelected() )
    {
        rStateSet.AddState( AccessibleStateType::SELECTED );
        ASSERT( bIsSelected, "bSelected out of sync" );
        ::vos::ORef < SwAccessibleContext > xThis( this );
        GetMap()->SetCursorContext( xThis );

        Window *pWin = GetWindow();
        if( pWin && pWin->HasFocus() )
            rStateSet.AddState( AccessibleStateType::FOCUSED );
    }
}

sal_uInt8 SwAccessibleFrameBase::GetNodeType( const SwFlyFrm *pFlyFrm )
{
    sal_uInt8 nType = ND_TEXTNODE;
    if( pFlyFrm->Lower() )
    {
         if( pFlyFrm->Lower()->IsNoTxtFrm() )
        {
            const SwCntntFrm *pCntFrm =
                static_cast<const SwCntntFrm *>( pFlyFrm->Lower() );
            nType = pCntFrm->GetNode()->GetNodeType();
        }
    }
    else
    {
        const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
        const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
        const SwNodeIndex *pNdIdx = rCntnt.GetCntntIdx();
        if( pNdIdx )
        {
            const SwCntntNode *pCNd =
                (pNdIdx->GetNodes())[pNdIdx->GetIndex()+1]->GetCntntNode();
            if( pCNd )
                nType = pCNd->GetNodeType();
        }
    }

    return nType;
}

SwAccessibleFrameBase::SwAccessibleFrameBase(
        SwAccessibleMap *pMap, sal_Int16 nRole,
        const SwFlyFrm *pFlyFrm ) :
    SwAccessibleContext( pMap, nRole, pFlyFrm ),
    bIsSelected( sal_False )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
    const_cast< SwFrmFmt * >( pFrmFmt )->Add( this );

    SetName( pFrmFmt->GetName() );

    bIsSelected = IsSelected();
}

void SwAccessibleFrameBase::_InvalidateCursorPos()
{
    sal_Bool bNewSelected = IsSelected();
    sal_Bool bOldSelected;

    {
        vos::OGuard aGuard( aMutex );
        bOldSelected = bIsSelected;
        bIsSelected = bNewSelected;
    }

    if( bNewSelected )
    {
        // remember that object as the one that has the caret. This is
        // neccessary to notify that object if the cursor leaves it.
        ::vos::ORef < SwAccessibleContext > xThis( this );
        GetMap()->SetCursorContext( xThis );
    }

    if( bOldSelected != bNewSelected )
    {
        Window *pWin = GetWindow();
        if( pWin && pWin->HasFocus() && bNewSelected )
            FireStateChangedEvent( AccessibleStateType::FOCUSED, bNewSelected );
        FireStateChangedEvent( AccessibleStateType::SELECTED, bNewSelected );
        if( pWin && pWin->HasFocus() && !bNewSelected )
            FireStateChangedEvent( AccessibleStateType::FOCUSED, bNewSelected );

        Reference< XAccessible > xParent( GetWeakParent() );
        if( xParent.is() )
        {
            SwAccessibleContext *pAcc =
                static_cast <SwAccessibleContext *>( xParent.get() );

            AccessibleEventObject aEvent;
            aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
            pAcc->FireAccessibleEvent( aEvent );
        }
    }
}

void SwAccessibleFrameBase::_InvalidateFocus()
{
    Window *pWin = GetWindow();
    if( pWin )
    {
        sal_Bool bSelected;

        {
            vos::OGuard aGuard( aMutex );
            bSelected = bIsSelected;
        }
        ASSERT( bSelected, "focus object should be selected" );

        FireStateChangedEvent( AccessibleStateType::FOCUSED,
                               pWin->HasFocus() && bSelected );
    }
}

sal_Bool SwAccessibleFrameBase::HasCursor()
{
    vos::OGuard aGuard( aMutex );
    return bIsSelected;
}

SwAccessibleFrameBase::~SwAccessibleFrameBase()
{
}

void SwAccessibleFrameBase::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
{
    sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
    const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm * >( GetFrm() );
    switch( nWhich )
    {
    case RES_NAME_CHANGED:
        if(  pFlyFrm )
        {
            const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
            ASSERT( pFrmFmt == GetRegisteredIn(), "invalid frame" );

            OUString sOldName( GetName() );
            ASSERT( !pOld ||
                    static_cast < SwStringMsgPoolItem * >( pOld )->GetString() == String( sOldName ),
                    "invalid old name" );

            const String& rNewName = pFrmFmt->GetName();
            SetName( rNewName );
            ASSERT( !pNew ||
                    static_cast < SwStringMsgPoolItem * >( pNew )->GetString() == rNewName,
                    "invalid new name" );

            if( sOldName != GetName() )
            {
                AccessibleEventObject aEvent;
                aEvent.EventId = AccessibleEventId::NAME_CHANGED;
                aEvent.OldValue <<= sOldName;
                aEvent.NewValue <<= GetName();
                FireAccessibleEvent( aEvent );
            }
        }
        break;
    case RES_OBJECTDYING:
        if( GetRegisteredIn() ==
                static_cast< SwModify *>( static_cast< SwPtrMsgPoolItem * >( pOld )->pObject ) )
            pRegisteredIn->Remove( this );
        break;

    case RES_FMT_CHG:
        if( static_cast< SwFmtChg * >(pNew)->pChangedFmt == GetRegisteredIn() &&
            static_cast< SwFmtChg * >(pOld)->pChangedFmt->IsFmtInDTOR() )
            pRegisteredIn->Remove( this );
        break;
    default:
        SwClient::Modify( pOld, pNew );
        break;
    }
}

void SwAccessibleFrameBase::Dispose( sal_Bool bRecursive )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    if( GetRegisteredIn() )
        pRegisteredIn->Remove( this );

    SwAccessibleContext::Dispose( bRecursive );
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.8.474); FILE MERGED 2006/09/01 17:51:11 kaib 1.8.474.1: #i68856# Added header markers and pch files<commit_after> /*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: accframebase.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 20:35:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLEEVENTID_HPP_
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX_
#include <unotools/accessiblestatesethelper.hxx>
#endif

#ifndef _VOS_MUTEX_HXX_ //autogen
#include <vos/mutex.hxx>
#endif
#ifndef _SV_SVAPP_HXX //autogen
#include <vcl/svapp.hxx>
#endif
#ifndef _SV_WINDOW_HXX
#include <vcl/window.hxx>
#endif

#ifndef _FRMFMT_HXX
#include <frmfmt.hxx>
#endif
#ifndef _NDNOTXT_HXX
#include <ndnotxt.hxx>
#endif
#ifndef _FLYFRM_HXX
#include <flyfrm.hxx>
#endif
#ifndef _CNTFRM_HXX
#include <cntfrm.hxx>
#endif
#ifndef _FMTCNTNT_HXX
#include <fmtcntnt.hxx>
#endif
#ifndef _NDINDEX_HXX
#include <ndindex.hxx>
#endif
#ifndef _FESH_HXX
#include "fesh.hxx"
#endif
#ifndef _HINTS_HXX
#include <hints.hxx>
#endif

#ifndef _ACCMAP_HXX
#include "accmap.hxx"
#endif
#ifndef _ACCFRAMEBASE_HXX
#include "accframebase.hxx"
#endif

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::accessibility;
using namespace ::rtl;

sal_Bool SwAccessibleFrameBase::IsSelected()
{
    sal_Bool bRet = sal_False;

    DBG_ASSERT( GetMap(), "no map?" );
    const ViewShell *pVSh = GetMap()->GetShell();
    DBG_ASSERT( pVSh, "no shell?" );
    if( pVSh->ISA( SwFEShell ) )
    {
        const SwFEShell *pFESh = static_cast< const SwFEShell * >( pVSh );
        const SwFrm *pFlyFrm = pFESh->GetCurrFlyFrm();
        if( pFlyFrm == GetFrm() )
            bRet = sal_True;
    }

    return bRet;
}

void SwAccessibleFrameBase::GetStates(
        ::utl::AccessibleStateSetHelper& rStateSet )
{
    SwAccessibleContext::GetStates( rStateSet );

    const ViewShell *pVSh = GetMap()->GetShell();
    DBG_ASSERT( pVSh, "no shell?" );
    sal_Bool bSelectable =  pVSh->ISA( SwFEShell );

    // SELECTABLE
    if( bSelectable )
        rStateSet.AddState( AccessibleStateType::SELECTABLE );

    // FOCUSABLE
    if( bSelectable )
        rStateSet.AddState( AccessibleStateType::FOCUSABLE );

    // SELECTED and FOCUSED
    if( IsSelected() )
    {
        rStateSet.AddState( AccessibleStateType::SELECTED );
        ASSERT( bIsSelected, "bSelected out of sync" );
        ::vos::ORef < SwAccessibleContext > xThis( this );
        GetMap()->SetCursorContext( xThis );

        Window *pWin = GetWindow();
        if( pWin && pWin->HasFocus() )
            rStateSet.AddState( AccessibleStateType::FOCUSED );
    }
}

sal_uInt8 SwAccessibleFrameBase::GetNodeType( const SwFlyFrm *pFlyFrm )
{
    sal_uInt8 nType = ND_TEXTNODE;
    if( pFlyFrm->Lower() )
    {
         if( pFlyFrm->Lower()->IsNoTxtFrm() )
        {
            const SwCntntFrm *pCntFrm =
                static_cast<const SwCntntFrm *>( pFlyFrm->Lower() );
            nType = pCntFrm->GetNode()->GetNodeType();
        }
    }
    else
    {
        const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
        const SwFmtCntnt& rCntnt = pFrmFmt->GetCntnt();
        const SwNodeIndex *pNdIdx = rCntnt.GetCntntIdx();
        if( pNdIdx )
        {
            const SwCntntNode *pCNd =
                (pNdIdx->GetNodes())[pNdIdx->GetIndex()+1]->GetCntntNode();
            if( pCNd )
                nType = pCNd->GetNodeType();
        }
    }

    return nType;
}

SwAccessibleFrameBase::SwAccessibleFrameBase(
        SwAccessibleMap *pMap, sal_Int16 nRole,
        const SwFlyFrm *pFlyFrm ) :
    SwAccessibleContext( pMap, nRole, pFlyFrm ),
    bIsSelected( sal_False )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
    const_cast< SwFrmFmt * >( pFrmFmt )->Add( this );

    SetName( pFrmFmt->GetName() );

    bIsSelected = IsSelected();
}

void SwAccessibleFrameBase::_InvalidateCursorPos()
{
    sal_Bool bNewSelected = IsSelected();
    sal_Bool bOldSelected;

    {
        vos::OGuard aGuard( aMutex );
        bOldSelected = bIsSelected;
        bIsSelected = bNewSelected;
    }

    if( bNewSelected )
    {
        // remember that object as the one that has the caret. This is
        // neccessary to notify that object if the cursor leaves it.
        ::vos::ORef < SwAccessibleContext > xThis( this );
        GetMap()->SetCursorContext( xThis );
    }

    if( bOldSelected != bNewSelected )
    {
        Window *pWin = GetWindow();
        if( pWin && pWin->HasFocus() && bNewSelected )
            FireStateChangedEvent( AccessibleStateType::FOCUSED, bNewSelected );
        FireStateChangedEvent( AccessibleStateType::SELECTED, bNewSelected );
        if( pWin && pWin->HasFocus() && !bNewSelected )
            FireStateChangedEvent( AccessibleStateType::FOCUSED, bNewSelected );

        Reference< XAccessible > xParent( GetWeakParent() );
        if( xParent.is() )
        {
            SwAccessibleContext *pAcc =
                static_cast <SwAccessibleContext *>( xParent.get() );

            AccessibleEventObject aEvent;
            aEvent.EventId = AccessibleEventId::SELECTION_CHANGED;
            pAcc->FireAccessibleEvent( aEvent );
        }
    }
}

void SwAccessibleFrameBase::_InvalidateFocus()
{
    Window *pWin = GetWindow();
    if( pWin )
    {
        sal_Bool bSelected;

        {
            vos::OGuard aGuard( aMutex );
            bSelected = bIsSelected;
        }
        ASSERT( bSelected, "focus object should be selected" );

        FireStateChangedEvent( AccessibleStateType::FOCUSED,
                               pWin->HasFocus() && bSelected );
    }
}

sal_Bool SwAccessibleFrameBase::HasCursor()
{
    vos::OGuard aGuard( aMutex );
    return bIsSelected;
}

SwAccessibleFrameBase::~SwAccessibleFrameBase()
{
}

void SwAccessibleFrameBase::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
{
    sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ;
    const SwFlyFrm *pFlyFrm = static_cast< const SwFlyFrm * >( GetFrm() );
    switch( nWhich )
    {
    case RES_NAME_CHANGED:
        if(  pFlyFrm )
        {
            const SwFrmFmt *pFrmFmt = pFlyFrm->GetFmt();
            ASSERT( pFrmFmt == GetRegisteredIn(), "invalid frame" );

            OUString sOldName( GetName() );
            ASSERT( !pOld ||
                    static_cast < SwStringMsgPoolItem * >( pOld )->GetString() == String( sOldName ),
                    "invalid old name" );

            const String& rNewName = pFrmFmt->GetName();
            SetName( rNewName );
            ASSERT( !pNew ||
                    static_cast < SwStringMsgPoolItem * >( pNew )->GetString() == rNewName,
                    "invalid new name" );

            if( sOldName != GetName() )
            {
                AccessibleEventObject aEvent;
                aEvent.EventId = AccessibleEventId::NAME_CHANGED;
                aEvent.OldValue <<= sOldName;
                aEvent.NewValue <<= GetName();
                FireAccessibleEvent( aEvent );
            }
        }
        break;
    case RES_OBJECTDYING:
        if( GetRegisteredIn() ==
                static_cast< SwModify *>( static_cast< SwPtrMsgPoolItem * >( pOld )->pObject ) )
            pRegisteredIn->Remove( this );
        break;

    case RES_FMT_CHG:
        if( static_cast< SwFmtChg * >(pNew)->pChangedFmt == GetRegisteredIn() &&
            static_cast< SwFmtChg * >(pOld)->pChangedFmt->IsFmtInDTOR() )
            pRegisteredIn->Remove( this );
        break;
    default:
        SwClient::Modify( pOld, pNew );
        break;
    }
}

void SwAccessibleFrameBase::Dispose( sal_Bool bRecursive )
{
    vos::OGuard aGuard(Application::GetSolarMutex());

    if( GetRegisteredIn() )
        pRegisteredIn->Remove( this );

    SwAccessibleContext::Dispose( bRecursive );
}
<|endoftext|>


<commit_before>/* Public Domain.  See the LICENSE file. */

/* A simple program to generate Pythagorean triples.   */
/* ie.  Integer solutions to:  a^2 + b^2 = c^2         */

/* To compile, the GMP library needs to be already installed.    */
/* See https://gmplib.org                                        */
/* On linux, try:  gcc ptriples.cpp -lgmp -o ptriples            */

/* A great source of info is the Wikipedia page:      */
/* http://en.wikipedia.org/wiki/Pythagorean_triple    */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmp.h>

struct tentry {
  mpz_t a;
  mpz_t b;
  mpz_t c;
};

struct ttable {
long             count;
struct tentry*   triples;
};

void AddPTriple( struct ttable*, mpz_t, mpz_t, mpz_t );
void Cleanup_ttable( struct ttable* );
int ttable_entry_cmpfunc( const void*, const void* );

int main( int argc, char * argv[] ) {

  if ( argc != 3 && argc != 4 ) {
    printf("\n");
    printf("For a^2 + b^2 = c^2 :\n");
    printf("\n");
    printf("Usage: ptriples [-p] c_min c_max\n\n\n");
    printf("Options:\n\n");
    printf("  -p -- primitive triples only\n\n");
    return 1;
  }

  int DoOnlyPrimitives = 0;
  if ( argc == 4 && strcmp( argv[1], "-p" ) == 0 )
    DoOnlyPrimitives = 1;

  mpz_t user_c_min;
  mpz_init_set_str( user_c_min,  argv[argc == 3 ? 1 : 2], 10 );

  mpz_t user_c_max;
  mpz_init_set_str( user_c_max,  argv[argc == 3 ? 2 : 3], 10 );

  if ( mpz_cmp_ui( user_c_min, 1 ) < 0 ) {
    printf("\nc_min must be >= 1.  Aborting.\n\n");
    mpz_clear( user_c_max );
    mpz_clear( user_c_min );
    return 1;
  }

  if ( mpz_cmp( user_c_min, user_c_max ) > 0 ) {
    printf("\nc_min must be <= c_max.  Aborting.\n\n");
    mpz_clear( user_c_max );
    mpz_clear( user_c_min );
    return 1;
  }

  mpz_t working_c_min;
  if ( DoOnlyPrimitives )
    mpz_init_set( working_c_min, user_c_min );
  else
    mpz_init_set_ui( working_c_min, 1 );

  // We are going to use Euclid's formula:
  // For arbitrary positive integers m and n, and m > n,
  // a = m^2 - n^2, b = 2mn, c = m^2 + n^2

  // In addition, we will restrict GCD(m,n) = 1 and m-n be
  // an odd number to guarantee that the triple is primitive.

  struct ttable triples;
  triples.count = 0;
  triples.triples = NULL;

  mpz_t a;
  mpz_init( a );
  mpz_t b;
  mpz_init( b );
  mpz_t c;
  mpz_init( c );

  mpz_t n;
  mpz_init( n );
  mpz_t m;
  mpz_init( m );

  // n can vary from 1 to no more than (c_max/2)^(1/2)
  mpz_t n_max;
  mpz_init_set( n_max, user_c_max );
  mpz_cdiv_q_2exp( n_max, n_max, 1 );
  mpz_sqrt( n_max, n_max );

  mpz_t m_min;
  mpz_init( m_min );

  mpz_t m_max;
  mpz_init( m_max );

  mpz_t n_squared;
  mpz_init( n_squared );

  mpz_t m_squared;
  mpz_init( m_squared );

  mpz_t gcd;
  mpz_init( gcd );

  mpz_t tempZ;
  mpz_init( tempZ );

  mpz_t k;
  mpz_init( k );

  mpz_t ka;
  mpz_init( ka );
  mpz_t kb;
  mpz_init( kb );
  mpz_t kc;
  mpz_init( kc );

  // iterate through n
  for ( mpz_set_ui( n, 1 );  mpz_cmp( n, n_max ) <= 0; mpz_add_ui( n, n, 1 ) ) {
    mpz_mul( n_squared, n, n );

    // compute m_min
    mpz_sub( m_min, working_c_min, n_squared );

    if ( mpz_cmp_ui( m_min, 1 ) < 0 )  // make sure mpz_sqrt() has a legal value
      mpz_set_ui( m_min, 1 );
    mpz_sqrt( m_min, m_min );
    mpz_sub_ui( m_min, m_min, 1 );  // subtract 1 just to be on the safe side

    // compute m_max
    mpz_sub( m_max, user_c_max, n_squared );
    if ( mpz_cmp_ui( m_max, 1 ) < 0 )  // make sure mpz_sqrt() has a legal value
      mpz_set_ui( m_max, 1 );
    mpz_sqrt( m_max, m_max );

    // calc first value of m
    if ( mpz_cmp( n, m_min ) < 0 ) {
      mpz_set( m, m_min );
      mpz_sub( tempZ, m, n );
      if ( mpz_divisible_ui_p( tempZ, 2 ) )
        mpz_add_ui( m, m, 1 );
    }
    else {
      mpz_set( m, n );
      mpz_add_ui( m, m, 1 );
    }

    // iterate through m
    for ( ; mpz_cmp( m, m_max ) <= 0; mpz_add_ui( m, m, 2 ) ) {

      // generate a primitive (a,b,c)
      mpz_gcd( gcd, m, n );
      if ( mpz_cmp_ui( gcd, 1 ) != 0 )
        continue;

      mpz_mul( m_squared, m, m );

      mpz_sub( a, m_squared, n_squared );

      mpz_mul( b, m, n );
      mpz_mul_ui( b, b, 2 );

      mpz_add( c, m_squared, n_squared );

      // check if primitive is outside our working range
      if ( mpz_cmp( c, working_c_min ) < 0 )
        continue;
      if ( mpz_cmp( c, user_c_max ) > 0 )
        continue;

      if ( DoOnlyPrimitives )
        AddPTriple( &triples, a, b, c );
      else {
        // iterate through k in: (k*a)^2 + (k*b)^2 = (k*c)^2
        mpz_fdiv_q( k, user_c_min, c );

        for ( mpz_mul( kc, c, k ); mpz_cmp( kc, user_c_max ) <= 0; mpz_add_ui( k, k, 1 ), mpz_mul( kc, c, k ) ) {

          if ( mpz_cmp( kc, user_c_min ) < 0 )
            continue;

          mpz_mul( ka, a, k );
          mpz_mul( kb, b, k );

          AddPTriple( &triples, ka, kb, kc );
        }
      }
    }
  }

  mpz_clear( kc );
  mpz_clear( kb );
  mpz_clear( ka );
  mpz_clear( k );

  qsort( triples.triples, triples.count, sizeof(struct tentry), ttable_entry_cmpfunc );

  // print
  long i;
  for ( i = 0; i < triples.count; i++ )
    gmp_printf("(%Zd,%Zd,%Zd)\n", triples.triples[i].a, triples.triples[i].b, triples.triples[i].c );

  mpz_clear( tempZ );
  mpz_clear( gcd );
  mpz_clear( m_squared );
  mpz_clear( n_squared );
  mpz_clear( m_max );
  mpz_clear( m_min );
  mpz_clear( n_max );
  mpz_clear( m );
  mpz_clear( n );
  mpz_clear( c );
  mpz_clear( b );
  mpz_clear( a );

  Cleanup_ttable( &triples );

  mpz_clear( working_c_min );
  mpz_clear( user_c_max );
  mpz_clear( user_c_min );

  return 0;
}

// Add an entry to TABLE2
void AddPTriple( struct ttable* the_ttable, mpz_t a, mpz_t b, mpz_t c ) {

  // allocate memory
  long index = 0;
  if ( the_ttable->count == 0 ) {
    the_ttable->count = 1;
    the_ttable->triples = (struct tentry*) calloc( 1, sizeof(struct tentry) );
  }
  else {
    the_ttable->count++;
    the_ttable->triples = (struct tentry*) realloc( the_ttable->triples, sizeof(struct tentry) * the_ttable->count );
    index = the_ttable->count - 1;
    memset( &the_ttable->triples[index], 0, sizeof(struct tentry) );
  }

  mpz_init_set( the_ttable->triples[index].a, mpz_cmp( a, b ) < 0 ? a : b );
  mpz_init_set( the_ttable->triples[index].b, mpz_cmp( a, b ) < 0 ? b : a );
  mpz_init_set( the_ttable->triples[index].c, c );
}

// Free the memory allocated
void Cleanup_ttable( struct ttable* the_ttable ) {

  if ( the_ttable == NULL )
    return;

  long i;
  for ( i = 0; i < the_ttable->count; i++ ) {
    mpz_clear( the_ttable->triples[i].a );
    mpz_clear( the_ttable->triples[i].b );
    mpz_clear( the_ttable->triples[i].c );
  }

  if ( the_ttable->triples != NULL ) {
    free( the_ttable->triples );
    the_ttable->triples = NULL;
  }

  the_ttable->count = 0;
}

int ttable_entry_cmpfunc( const void* p1, const void* p2 ) {

  struct tentry*   entry1 = (struct tentry*)p1;
  struct tentry*   entry2 = (struct tentry*)p2;

  int cmpval = mpz_cmp( entry1->c, entry2->c );
  if ( cmpval == 0 )
      cmpval = mpz_cmp( entry1->b, entry2->b );
  if ( cmpval == 0 )
      cmpval = mpz_cmp( entry1->c, entry2->c );

  return cmpval;
}

<commit_msg>Remove useless compare statement in qsort comparison function.<commit_after>/* Public Domain.  See the LICENSE file. */

/* A simple program to generate Pythagorean triples.   */
/* ie.  Integer solutions to:  a^2 + b^2 = c^2         */

/* To compile, the GMP library needs to be already installed.    */
/* See https://gmplib.org                                        */
/* On linux, try:  gcc ptriples.cpp -lgmp -o ptriples            */

/* A great source of info is the Wikipedia page:      */
/* http://en.wikipedia.org/wiki/Pythagorean_triple    */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmp.h>

struct tentry {
  mpz_t a;
  mpz_t b;
  mpz_t c;
};

struct ttable {
long             count;
struct tentry*   triples;
};

void AddPTriple( struct ttable*, mpz_t, mpz_t, mpz_t );
void Cleanup_ttable( struct ttable* );
int ttable_entry_cmpfunc( const void*, const void* );

int main( int argc, char * argv[] ) {

  if ( argc != 3 && argc != 4 ) {
    printf("\n");
    printf("For a^2 + b^2 = c^2 :\n");
    printf("\n");
    printf("Usage: ptriples [-p] c_min c_max\n\n\n");
    printf("Options:\n\n");
    printf("  -p -- primitive triples only\n\n");
    return 1;
  }

  int DoOnlyPrimitives = 0;
  if ( argc == 4 && strcmp( argv[1], "-p" ) == 0 )
    DoOnlyPrimitives = 1;

  mpz_t user_c_min;
  mpz_init_set_str( user_c_min,  argv[argc == 3 ? 1 : 2], 10 );

  mpz_t user_c_max;
  mpz_init_set_str( user_c_max,  argv[argc == 3 ? 2 : 3], 10 );

  if ( mpz_cmp_ui( user_c_min, 1 ) < 0 ) {
    printf("\nc_min must be >= 1.  Aborting.\n\n");
    mpz_clear( user_c_max );
    mpz_clear( user_c_min );
    return 1;
  }

  if ( mpz_cmp( user_c_min, user_c_max ) > 0 ) {
    printf("\nc_min must be <= c_max.  Aborting.\n\n");
    mpz_clear( user_c_max );
    mpz_clear( user_c_min );
    return 1;
  }

  mpz_t working_c_min;
  if ( DoOnlyPrimitives )
    mpz_init_set( working_c_min, user_c_min );
  else
    mpz_init_set_ui( working_c_min, 1 );

  // We are going to use Euclid's formula:
  // For arbitrary positive integers m and n, and m > n,
  // a = m^2 - n^2, b = 2mn, c = m^2 + n^2

  // In addition, we will restrict GCD(m,n) = 1 and m-n be
  // an odd number to guarantee that the triple is primitive.

  struct ttable triples;
  triples.count = 0;
  triples.triples = NULL;

  mpz_t a;
  mpz_init( a );
  mpz_t b;
  mpz_init( b );
  mpz_t c;
  mpz_init( c );

  mpz_t n;
  mpz_init( n );
  mpz_t m;
  mpz_init( m );

  // n can vary from 1 to no more than (c_max/2)^(1/2)
  mpz_t n_max;
  mpz_init_set( n_max, user_c_max );
  mpz_cdiv_q_2exp( n_max, n_max, 1 );
  mpz_sqrt( n_max, n_max );

  mpz_t m_min;
  mpz_init( m_min );

  mpz_t m_max;
  mpz_init( m_max );

  mpz_t n_squared;
  mpz_init( n_squared );

  mpz_t m_squared;
  mpz_init( m_squared );

  mpz_t gcd;
  mpz_init( gcd );

  mpz_t tempZ;
  mpz_init( tempZ );

  mpz_t k;
  mpz_init( k );

  mpz_t ka;
  mpz_init( ka );
  mpz_t kb;
  mpz_init( kb );
  mpz_t kc;
  mpz_init( kc );

  // iterate through n
  for ( mpz_set_ui( n, 1 );  mpz_cmp( n, n_max ) <= 0; mpz_add_ui( n, n, 1 ) ) {
    mpz_mul( n_squared, n, n );

    // compute m_min
    mpz_sub( m_min, working_c_min, n_squared );

    if ( mpz_cmp_ui( m_min, 1 ) < 0 )  // make sure mpz_sqrt() has a legal value
      mpz_set_ui( m_min, 1 );
    mpz_sqrt( m_min, m_min );
    mpz_sub_ui( m_min, m_min, 1 );  // subtract 1 just to be on the safe side

    // compute m_max
    mpz_sub( m_max, user_c_max, n_squared );
    if ( mpz_cmp_ui( m_max, 1 ) < 0 )  // make sure mpz_sqrt() has a legal value
      mpz_set_ui( m_max, 1 );
    mpz_sqrt( m_max, m_max );

    // calc first value of m
    if ( mpz_cmp( n, m_min ) < 0 ) {
      mpz_set( m, m_min );
      mpz_sub( tempZ, m, n );
      if ( mpz_divisible_ui_p( tempZ, 2 ) )
        mpz_add_ui( m, m, 1 );
    }
    else {
      mpz_set( m, n );
      mpz_add_ui( m, m, 1 );
    }

    // iterate through m
    for ( ; mpz_cmp( m, m_max ) <= 0; mpz_add_ui( m, m, 2 ) ) {

      // generate a primitive (a,b,c)
      mpz_gcd( gcd, m, n );
      if ( mpz_cmp_ui( gcd, 1 ) != 0 )
        continue;

      mpz_mul( m_squared, m, m );

      mpz_sub( a, m_squared, n_squared );

      mpz_mul( b, m, n );
      mpz_mul_ui( b, b, 2 );

      mpz_add( c, m_squared, n_squared );

      // check if primitive is outside our working range
      if ( mpz_cmp( c, working_c_min ) < 0 )
        continue;
      if ( mpz_cmp( c, user_c_max ) > 0 )
        continue;

      if ( DoOnlyPrimitives )
        AddPTriple( &triples, a, b, c );
      else {
        // iterate through k in: (k*a)^2 + (k*b)^2 = (k*c)^2
        mpz_fdiv_q( k, user_c_min, c );

        for ( mpz_mul( kc, c, k ); mpz_cmp( kc, user_c_max ) <= 0; mpz_add_ui( k, k, 1 ), mpz_mul( kc, c, k ) ) {

          if ( mpz_cmp( kc, user_c_min ) < 0 )
            continue;

          mpz_mul( ka, a, k );
          mpz_mul( kb, b, k );

          AddPTriple( &triples, ka, kb, kc );
        }
      }
    }
  }

  mpz_clear( kc );
  mpz_clear( kb );
  mpz_clear( ka );
  mpz_clear( k );

  qsort( triples.triples, triples.count, sizeof(struct tentry), ttable_entry_cmpfunc );

  // print
  long i;
  for ( i = 0; i < triples.count; i++ )
    gmp_printf("(%Zd,%Zd,%Zd)\n", triples.triples[i].a, triples.triples[i].b, triples.triples[i].c );

  mpz_clear( tempZ );
  mpz_clear( gcd );
  mpz_clear( m_squared );
  mpz_clear( n_squared );
  mpz_clear( m_max );
  mpz_clear( m_min );
  mpz_clear( n_max );
  mpz_clear( m );
  mpz_clear( n );
  mpz_clear( c );
  mpz_clear( b );
  mpz_clear( a );

  Cleanup_ttable( &triples );

  mpz_clear( working_c_min );
  mpz_clear( user_c_max );
  mpz_clear( user_c_min );

  return 0;
}

// Add an entry to TABLE2
void AddPTriple( struct ttable* the_ttable, mpz_t a, mpz_t b, mpz_t c ) {

  // allocate memory
  long index = 0;
  if ( the_ttable->count == 0 ) {
    the_ttable->count = 1;
    the_ttable->triples = (struct tentry*) calloc( 1, sizeof(struct tentry) );
  }
  else {
    the_ttable->count++;
    the_ttable->triples = (struct tentry*) realloc( the_ttable->triples, sizeof(struct tentry) * the_ttable->count );
    index = the_ttable->count - 1;
    memset( &the_ttable->triples[index], 0, sizeof(struct tentry) );
  }

  mpz_init_set( the_ttable->triples[index].a, mpz_cmp( a, b ) < 0 ? a : b );
  mpz_init_set( the_ttable->triples[index].b, mpz_cmp( a, b ) < 0 ? b : a );
  mpz_init_set( the_ttable->triples[index].c, c );
}

// Free the memory allocated
void Cleanup_ttable( struct ttable* the_ttable ) {

  if ( the_ttable == NULL )
    return;

  long i;
  for ( i = 0; i < the_ttable->count; i++ ) {
    mpz_clear( the_ttable->triples[i].a );
    mpz_clear( the_ttable->triples[i].b );
    mpz_clear( the_ttable->triples[i].c );
  }

  if ( the_ttable->triples != NULL ) {
    free( the_ttable->triples );
    the_ttable->triples = NULL;
  }

  the_ttable->count = 0;
}

int ttable_entry_cmpfunc( const void* p1, const void* p2 ) {

  struct tentry*   entry1 = (struct tentry*)p1;
  struct tentry*   entry2 = (struct tentry*)p2;

  int cmpval = mpz_cmp( entry1->c, entry2->c );
  if ( cmpval == 0 )
      cmpval = mpz_cmp( entry1->b, entry2->b );

  return cmpval;
}

<|endoftext|>