<commit_before>#ifndef MAZE_ALGORITHM_C
#define MAZE_ALGORITHM_C

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

#include "MazeAlgorithm.h"
#include "MazeMap.h"

// computes the flood fill for the first time (center is the target)
void malgo_floodfill_compute(MazeMap* mm, ff_map* in)
{
	// blanks out the array to null values
	memset(in, MALGO_FF_BAD, sizeof(ff_map));

	// set the inner four values to 0 (this is the target)
	int centerRow = MAZE_HEIGHT / 2 - 1;
	int centerCol = MAZE_WIDTH / 2 - 1;

	in->array[centerRow][centerCol] = 0;
	in->array[centerRow][centerCol + 1] = 0;
	in->array[centerRow + 1][centerCol] = 0;
	in->array[centerRow + 1][centerCol + 1] = 0;

	// now keep looping in each direction until the values have been populated
	bool isPopulated = false;
	//while(!isPopulated) {
	for (int dumbshit = 0; dumbshit < 100000; dumbshit++) {

		// SOUTH to NORTH
		for (int row = 0; row < (MAZE_HEIGHT-1); row++) {
			for (int col = 0; col < MAZE_WIDTH; col++) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, NORTH);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get the value of the next column
				int nextVal = in->array[row + 1][col];

				// if the next value isn't bad, set the current one to it + 1
				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}

		// NORTH to SOUTH
		for (int row = MAZE_HEIGHT-1; row > 0; row--) {
			for (int col = 0; col < MAZE_WIDTH; col++) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, SOUTH);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get next value
				int nextVal = in->array[row - 1][col];

				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}

		// WEST to EAST
		for (int row = 0; row < MAZE_HEIGHT; row++) {
			for (int col = 0; col < (MAZE_WIDTH-1); col++) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, EAST);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get next val
				int nextVal = in->array[row][col + 1];

				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}

		// EAST to WEST
		for (int row = 0; row < MAZE_HEIGHT; row++) {
			for (int col = MAZE_WIDTH-1; col > 0; col--) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, WEST);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get the next val
				int nextVal = in->array[row][col - 1];

				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}
	}
}

// retargets the flood fill map
// ** UNTESTED **	-- this will be wrong with the middle zero blocks
void malgo_floodfill_recompute_target(int targetX, int targetY, ff_map* in)
{
	// find the current target
	int currentX = MALGO_FF_BAD;
	int currentY = MALGO_FF_BAD;
	for (int row = 0; row < MAZE_HEIGHT; row++) {
		for (int col = 0; col < MAZE_WIDTH; col++) {
			int value = in->array[row][col];

			if (value == 0) {
				currentX = col;
				currentY = row;

				break;
			}
		}

		// if inner forloop found a match, break out of this one
		if (currentX != MALGO_FF_BAD) {
			break;
		}
	}

	// the new difference will be the current value of the new target
	int difference = in->array[currentY][currentX];

	// displace the rest of the array
	for (int row = 0; row < MAZE_HEIGHT; row++) {
		for (int col = 0; col < MAZE_WIDTH; col++) {

			// make sure the value is always positive
			int curValue = in->array[row][col];
			if (difference > curValue) {
				in->array[row][col] = difference - curValue;
			}
			else {
				in->array[row][col] = curValue - difference;
			}
		}
	}
}

// uses floodfill to determine where to go
Direction malgo_floodfill_suggest_turn(int xPos, int yPos, MazeMap *mazeMap, ff_map* ffMap)
{
	int minVal =  100000;
	Direction minDir = EAST;

	bool eastWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, EAST);
	bool southWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, SOUTH);
	bool westWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, WEST);
	bool northWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, NORTH);

	int eastVal = 10000; int southVal = 10000; int westVal = 10000; int northVal = 10000;
	if (!eastWall) {
		eastVal = ffMap->array[yPos][xPos + 1];
	}
	if (!southWall) {
		southVal = ffMap->array[yPos - 1][xPos];
	}
	if (!westWall) {
		westVal = ffMap->array[yPos][xPos - 1];
	}
	if (!northWall) {
		northVal = ffMap->array[yPos + 1][xPos];
	}

	//printf("East: %d", eastWall);
	//printf("South: %d", southWall);
	//printf("West: %d", westWall);
	//printf("North: %d", northWall);

	printf("E: %d, S: %d, W: %d, N: %d\n", eastWall, southWall, westWall, northWall);
	printf("E: %d, S: %d, W: %d, N: %d\n", eastVal, southVal, westVal, northVal);

	if (!eastWall && eastVal < minVal) {
		printf("east is min\n");
		minDir = EAST;
		minVal = eastVal;
	}
	if (!southWall && southVal < minVal) {
		printf("south is min\n");
		minDir = SOUTH;
		minVal = southVal;
	}
	if (!westWall && westVal < minVal) {
		printf("west is min\n");
		minDir = WEST;
		minVal = westVal;
	}
	if (!northWall && northVal < minVal) {
		printf("north is min\n");
		minDir = NORTH;
	}

	return minDir;
}

#endif
<commit_msg>cleaning up the code literally<commit_after>#ifndef MAZE_ALGORITHM_C
#define MAZE_ALGORITHM_C

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

#include "MazeAlgorithm.h"
#include "MazeMap.h"

// computes the flood fill for the first time (center is the target)
void malgo_floodfill_compute(MazeMap* mm, ff_map* in)
{
	// blanks out the array to null values
	memset(in, MALGO_FF_BAD, sizeof(ff_map));

	// set the inner four values to 0 (this is the target)
	int centerRow = MAZE_HEIGHT / 2 - 1;
	int centerCol = MAZE_WIDTH / 2 - 1;

	in->array[centerRow][centerCol] = 0;
	in->array[centerRow][centerCol + 1] = 0;
	in->array[centerRow + 1][centerCol] = 0;
	in->array[centerRow + 1][centerCol + 1] = 0;

	// now keep looping in each direction until the values have been populated
	bool isPopulated = false;
	//while(!isPopulated) {
	for (int stupid = 0; stupid < 100000; stupid++) {

		// SOUTH to NORTH
		for (int row = 0; row < (MAZE_HEIGHT-1); row++) {
			for (int col = 0; col < MAZE_WIDTH; col++) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, NORTH);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get the value of the next column
				int nextVal = in->array[row + 1][col];

				// if the next value isn't bad, set the current one to it + 1
				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}

		// NORTH to SOUTH
		for (int row = MAZE_HEIGHT-1; row > 0; row--) {
			for (int col = 0; col < MAZE_WIDTH; col++) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, SOUTH);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get next value
				int nextVal = in->array[row - 1][col];

				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}

		// WEST to EAST
		for (int row = 0; row < MAZE_HEIGHT; row++) {
			for (int col = 0; col < (MAZE_WIDTH-1); col++) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, EAST);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get next val
				int nextVal = in->array[row][col + 1];

				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}

		// EAST to WEST
		for (int row = 0; row < MAZE_HEIGHT; row++) {
			for (int col = MAZE_WIDTH-1; col > 0; col--) {

				int curVal = in->array[row][col];
				if (curVal != MALGO_FF_BAD || curVal == 0) {
					continue;
				}

				bool wallExists = mazemap_does_wall_exist(mm, col, row, WEST);	// bottom left is (0,0)
				if (wallExists) {
					continue;
				}

				// get the next val
				int nextVal = in->array[row][col - 1];

				if (nextVal != MALGO_FF_BAD) {
					in->array[row][col] = nextVal + 1;
				}
			}
		}
	}
}

// retargets the flood fill map
// ** UNTESTED **	-- this will be wrong with the middle zero blocks
void malgo_floodfill_recompute_target(int targetX, int targetY, ff_map* in)
{
	// find the current target
	int currentX = MALGO_FF_BAD;
	int currentY = MALGO_FF_BAD;
	for (int row = 0; row < MAZE_HEIGHT; row++) {
		for (int col = 0; col < MAZE_WIDTH; col++) {
			int value = in->array[row][col];

			if (value == 0) {
				currentX = col;
				currentY = row;

				break;
			}
		}

		// if inner forloop found a match, break out of this one
		if (currentX != MALGO_FF_BAD) {
			break;
		}
	}

	// the new difference will be the current value of the new target
	int difference = in->array[currentY][currentX];

	// displace the rest of the array
	for (int row = 0; row < MAZE_HEIGHT; row++) {
		for (int col = 0; col < MAZE_WIDTH; col++) {

			// make sure the value is always positive
			int curValue = in->array[row][col];
			if (difference > curValue) {
				in->array[row][col] = difference - curValue;
			}
			else {
				in->array[row][col] = curValue - difference;
			}
		}
	}
}

// uses floodfill to determine where to go
Direction malgo_floodfill_suggest_turn(int xPos, int yPos, MazeMap *mazeMap, ff_map* ffMap)
{
	int minVal =  100000;
	Direction minDir = EAST;

	bool eastWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, EAST);
	bool southWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, SOUTH);
	bool westWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, WEST);
	bool northWall = mazemap_does_wall_exist(mazeMap, xPos, yPos, NORTH);

	int eastVal = 10000; int southVal = 10000; int westVal = 10000; int northVal = 10000;
	if (!eastWall) {
		eastVal = ffMap->array[yPos][xPos + 1];
	}
	if (!southWall) {
		southVal = ffMap->array[yPos - 1][xPos];
	}
	if (!westWall) {
		westVal = ffMap->array[yPos][xPos - 1];
	}
	if (!northWall) {
		northVal = ffMap->array[yPos + 1][xPos];
	}

	//printf("East: %d", eastWall);
	//printf("South: %d", southWall);
	//printf("West: %d", westWall);
	//printf("North: %d", northWall);

	printf("E: %d, S: %d, W: %d, N: %d\n", eastWall, southWall, westWall, northWall);
	printf("E: %d, S: %d, W: %d, N: %d\n", eastVal, southVal, westVal, northVal);

	if (!eastWall && eastVal < minVal) {
		printf("east is min\n");
		minDir = EAST;
		minVal = eastVal;
	}
	if (!southWall && southVal < minVal) {
		printf("south is min\n");
		minDir = SOUTH;
		minVal = southVal;
	}
	if (!westWall && westVal < minVal) {
		printf("west is min\n");
		minDir = WEST;
		minVal = westVal;
	}
	if (!northWall && northVal < minVal) {
		printf("north is min\n");
		minDir = NORTH;
	}

	return minDir;
}

#endif
<|endoftext|>


<commit_before>/**
 * Tests of str_rope and rope_node.
 *
 * @author Jean-Claude Paquin
 **/

#include <catch.hpp>
#include <primitives/str_rope.h>

TEST_CASE("Empty rope_node", "[rope_node]") {
    rope_node node;

    SECTION("Empty node has nullptr left & right") {
        REQUIRE(!node.data.left);
        REQUIRE(!node.data.right);
    }

    SECTION("Empty node to string") {
        REQUIRE(*node.to_string() == "");
    }

    SECTION("Empty node is not a leaf") {
        REQUIRE(!node.is_leaf);
    }
}

TEST_CASE("String rope_node", "[rope_node]") {
    rope_node node(std::string("wow!"));

    SECTION("String node is a leaf") {
        REQUIRE(node.is_leaf);
    }
}

TEST_CASE("Copy constructor for rope_node", "[rope_node]") {
    SECTION("Copied node is a leaf node") {
        rope_node node(std::string("that's a low price!"));
        rope_node dupl(node);

        REQUIRE(*dupl.to_string() == *node.to_string());
        REQUIRE(dupl.is_leaf);
    }

    SECTION("Copied node is not a leaf node") {
        rope_node node;
        rope_node dupl(node);

        REQUIRE(!dupl.is_leaf);
    }
}

<commit_msg>More test file cleaning<commit_after>/**
 * Tests of str_rope and rope_node.
 *
 * @author Jean-Claude Paquin
 **/

#include <catch.hpp>
#include <primitives/str_rope.h>

TEST_CASE("Empty rope_node", "[rope_node]") {
    rope_node node;

    REQUIRE(!node.data.left);
    REQUIRE(!node.data.right);

    REQUIRE(*node.to_string() == "");

    REQUIRE(!node.is_leaf);

    REQUIRE(node.actual_size == 0);
}

TEST_CASE("String rope_node", "[rope_node]") {
    rope_node node(std::string("wow!"));

    REQUIRE(*node.to_string() == "wow!");

    REQUIRE(node.is_leaf);

    REQUIRE(node.actual_size == 4);
}

TEST_CASE("Copy constructor for rope_node", "[rope_node]") {
    SECTION("Copied node is a leaf node") {
        rope_node node(std::string("that's a low price!"));
        rope_node dupl(node);

        REQUIRE(*dupl.to_string() == *node.to_string());
        REQUIRE(dupl.is_leaf);
    }

    SECTION("Copied node is not a leaf node") {
        rope_node node;
        rope_node dupl(node);

        REQUIRE(!dupl.is_leaf);
    }
}

<|endoftext|>


<commit_before>#ifndef MJOLNIR_TEST_UTIL_STUB_POTENTIAL_HPP
#define MJOLNIR_TEST_UTIL_STUB_POTENTIAL_HPP
#include <mjolnir/math/Vector.hpp>
#include <mjolnir/core/System.hpp>
#include <mjolnir/forcefield/global/ParameterList.hpp>

namespace mjolnir
{
namespace test
{

template<typename realT>
class StubPotential
{
  public:
    using real_type      = realT;
    using parameter_type = std::pair<std::size_t, std::size_t>;
    using self_type      = StubPotential<real_type>;

    static constexpr real_type default_cutoff() noexcept
    {
        return real_type(2.0);
    }
    static constexpr parameter_type default_parameter() noexcept
    {
        return parameter_type{0, 0};
    }

    static void set_cutoff_ratio(const real_type rc)
    {
        return;
    }

    static constexpr real_type cutoff_ratio   = real_type(1);
    static constexpr real_type coef_at_cutoff = real_type(0);

  public:

    explicit StubPotential(const parameter_type& para) noexcept
        : para_(para)
    {}
    ~StubPotential() = default;

    real_type potential(const real_type) const noexcept
    {
        return 0.0;
    }
    real_type derivative(const real_type) const noexcept
    {
        return 0.0;
    }

    template<typename T>
    void initialize(const System<T>&) noexcept {return;}

    template<typename T>
    void update(const System<T>&) noexcept {return;}

    static const char* name() noexcept {return "Stub";}

    parameter_type parameter()   const noexcept {return this->para_;}

    real_type cutoff()  const noexcept
    {
        return 0.0;
    }

  public:

    // To culculate cutoff distance, we need to find the maximum sigma in the
    // existing parameters. But the list of parameters will be given in a variety
    // of ways, like Lorentz-Bertherot rule, combination table, or another way
    // of combination rules.
    //     To find the maximum parameter, we need to provide a way to compare
    // parameters. But the way depends on the functional form of a potential.
    // So this comparator should be defined in a Potential class.
    struct parameter_comparator
    {
        constexpr bool
        operator()(const parameter_type& lhs, const parameter_type& rhs) const noexcept
        {
            return lhs.first < rhs.first;
        }
    };

  private:

    parameter_type para_;
};
template<typename realT>
constexpr typename StubPotential<realT>::real_type StubPotential<realT>::cutoff_ratio;
template<typename realT>
constexpr typename StubPotential<realT>::real_type StubPotential<realT>::coef_at_cutoff;

template<typename traitsT>
struct StubParameterList
    : public ParameterListBase<traitsT, StubPotential<typename traitsT::real_type>>
{
    using traits_type          = traitsT;
    using real_type            = typename traits_type::real_type;
    using potential_type       = StubPotential<real_type>;
    using base_type            = ParameterListBase<traits_type, potential_type>;

    using pair_parameter_type  = typename potential_type::parameter_type;

    using system_type          = System<traits_type>;
    using topology_type        = Topology;
    using molecule_id_type     = typename topology_type::molecule_id_type;
    using group_id_type        = typename topology_type::group_id_type;
    using connection_kind_type = typename topology_type::connection_kind_type;
    using ignore_molecule_type = IgnoreMolecule<molecule_id_type>;
    using ignore_group_type    = IgnoreGroup   <group_id_type>;
    using exclusion_list_type  = ExclusionList<traits_type>;

    explicit StubParameterList(const real_type cutoff_ratio,
        const std::vector<std::size_t>& parameters,
        const std::map<connection_kind_type, std::size_t>& exclusions,
        ignore_molecule_type ignore_mol, ignore_group_type ignore_grp)
        : cutoff_(cutoff_ratio), participants_(parameters),
          exclusion_list_(exclusions, std::move(ignore_mol), std::move(ignore_grp))
    {}

    real_type max_cutoff_length() const noexcept override {return this->cutoff_;}

    pair_parameter_type prepare_params(std::size_t i, std::size_t j) const noexcept override
    {
        return pair_parameter_type{i, j};
    }

    void initialize(const system_type& sys, const topology_type& topol) noexcept override
    {
        this->update(sys, topol);
        return;
    }
    void update(const system_type& sys, const topology_type& topol) noexcept override
    {
        // update exclusion list based on sys.topology()
        exclusion_list_.make(sys, topol);
        return;
    }

    std::vector<std::size_t> const& participants() const noexcept override
    {
        return this->participants_;
    }
    mjolnir::range<typename std::vector<std::size_t>::const_iterator>
    leading_participants() const noexcept override
    {
        return mjolnir::make_range(participants_.begin(), std::prev(participants_.end()));
    }
    mjolnir::range<typename std::vector<std::size_t>::const_iterator>
    possible_partners_of(const std::size_t participant_idx,
                         const std::size_t /*particle_idx*/) const noexcept override
    {
        return mjolnir::make_range(participants_.begin() + participant_idx + 1,
                                   participants_.end());
    }
    bool has_interaction(const std::size_t i, const std::size_t j) const noexcept override
    {
        return (i < j);
    }

    std::string name() const {return "Stub";}

    exclusion_list_type const& exclusion_list() const noexcept override
    {
        return exclusion_list_; // for testing
    }

    base_type* clone() const override
    {
        return new StubParameterList(*this);
    }

  private:

    real_type cutoff_;
    std::vector<std::size_t> participants_;
    exclusion_list_type  exclusion_list_;
};

} // test
} // mjolnir
#endif// MJOLNIR_TEST_UTIL_CHECK_FORCE_HPP
<commit_msg>test: update stub_potential<commit_after>#ifndef MJOLNIR_TEST_UTIL_STUB_POTENTIAL_HPP
#define MJOLNIR_TEST_UTIL_STUB_POTENTIAL_HPP
#include <mjolnir/math/Vector.hpp>
#include <mjolnir/core/System.hpp>
#include <mjolnir/forcefield/global/ParameterList.hpp>

namespace mjolnir
{
namespace test
{

template<typename realT>
class StubPotential
{
  public:
    using real_type = realT;
    struct parameter_type
    {
        std::size_t i;
        std::size_t j;
    };

    static constexpr real_type default_cutoff() noexcept
    {
        return real_type(2.0);
    }

  public:

    StubPotential() noexcept {}
    ~StubPotential() = default;

    real_type potential(const real_type, const parameter_type&) const noexcept
    {
        return 0.0;
    }
    real_type derivative(const real_type, const parameter_type&) const noexcept
    {
        return 0.0;
    }

    template<typename T>
    void initialize(const System<T>&) noexcept {return;}

    template<typename T>
    void update(const System<T>&) noexcept {return;}

    template<typename InputIterator>
    real_type max_cutoff(const InputIterator, const InputIterator) const noexcept
    {
        return 2.0;
    }
    real_type absolute_cutoff(const parameter_type&) const noexcept
    {
        return 2.0;
    }

    static const char* name() noexcept {return "Stub";}
};

template<typename traitsT>
struct StubParameterList
    : public ParameterListBase<traitsT, StubPotential<typename traitsT::real_type>>
{
    using traits_type          = traitsT;
    using real_type            = typename traits_type::real_type;
    using potential_type       = StubPotential<real_type>;
    using base_type            = ParameterListBase<traits_type, potential_type>;

    using pair_parameter_type  = typename potential_type::parameter_type;

    using system_type          = System<traits_type>;
    using topology_type        = Topology;
    using molecule_id_type     = typename topology_type::molecule_id_type;
    using group_id_type        = typename topology_type::group_id_type;
    using connection_kind_type = typename topology_type::connection_kind_type;
    using ignore_molecule_type = IgnoreMolecule<molecule_id_type>;
    using ignore_group_type    = IgnoreGroup   <group_id_type>;
    using exclusion_list_type  = ExclusionList<traits_type>;

    explicit StubParameterList(const double cutoff,
        const std::vector<std::size_t>& parameters,
        const std::map<connection_kind_type, std::size_t>& exclusions,
        ignore_molecule_type ignore_mol, ignore_group_type ignore_grp)
        : cutoff_(cutoff), participants_(parameters),
          exclusion_list_(exclusions, std::move(ignore_mol), std::move(ignore_grp))
    {}

    real_type max_cutoff_length() const noexcept override {return cutoff_;}

    pair_parameter_type prepare_params(std::size_t i, std::size_t j) const noexcept override
    {
        return pair_parameter_type{i, j};
    }

    void initialize(const system_type& sys, const topology_type& topol,
                    const potential_type& pot) noexcept override
    {
        this->update(sys, topol, pot);
        return;
    }
    void update(const system_type& sys, const topology_type& topol,
                const potential_type&) noexcept override
    {
        // update exclusion list based on sys.topology()
        exclusion_list_.make(sys, topol);
        return;
    }

    std::vector<std::size_t> const& participants() const noexcept override
    {
        return this->participants_;
    }
    mjolnir::range<typename std::vector<std::size_t>::const_iterator>
    leading_participants() const noexcept override
    {
        return mjolnir::make_range(participants_.begin(), std::prev(participants_.end()));
    }
    mjolnir::range<typename std::vector<std::size_t>::const_iterator>
    possible_partners_of(const std::size_t participant_idx,
                         const std::size_t /*particle_idx*/) const noexcept override
    {
        return mjolnir::make_range(participants_.begin() + participant_idx + 1,
                                   participants_.end());
    }
    bool has_interaction(const std::size_t i, const std::size_t j) const noexcept override
    {
        return (i < j);
    }

    std::string name() const {return "Stub";}

    exclusion_list_type const& exclusion_list() const noexcept override
    {
        return exclusion_list_; // for testing
    }

    base_type* clone() const override
    {
        return new StubParameterList(*this);
    }

  private:

    real_type cutoff_;
    std::vector<std::size_t> participants_;
    exclusion_list_type  exclusion_list_;
};

} // test
} // mjolnir
#endif// MJOLNIR_TEST_UTIL_CHECK_FORCE_HPP
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------

#include "PIDController.h"

//------------------------------------------------------------------------------
// Constructors
//------------------------------------------------------------------------------

// Default constructor
PIDController::PIDController() {
    this->setGains(0, 0, 0);
    this->setInputLimits(-1, -1);
    this->setOutputLimits(-1, -1);
    this->reset();
}

// Just gains, no limits
PIDController::PIDController(double kp, double ki, double kd) {
    this->setGains(kp, ki, kd);
    this->setInputLimits(-1, -1);
    this->setOutputLimits(-1, -1);
    this->reset();
}
// Gains and output limits
PIDController::PIDController(double kp, double ki, double kd, double lowerOutputLimit, double upperOutputLimit) {
    this->setGains(kp, ki, kd);
    this->setInputLimits(-1, -1);
    this->setOutputLimits(lowerOutputLimit, upperOutputLimit);
    this->reset();
}

// All gains and limits
PIDController::PIDController(double kp, double ki, double kd, double lowerInputLimit, double upperInputLimit, double lowerOutputLimit, double upperOutputLimit) {
    this->setGains(kp, ki, kd);
    this->setInputLimits(lowerInputLimit, upperInputLimit);
    this->setOutputLimits(lowerOutputLimit, upperOutputLimit);
    this->reset();
}

// Copy constructor
PIDController::PIDController(const PIDController& orig) {
    this->setGains(orig.kp, orig.ki, orig.kd);
    this->setInputLimits(orig.lowerInputLimit, orig.upperInputLimit);
    this->setOutputLimits(orig.lowerOutputLimit, orig.lowerInputLimit);
    integrator = orig.integrator;
    lastError = orig.lastError;
    peakTime = orig.peakTime;
    settlingTime = orig.settlingTime;
    percentOvershoot = orig.percentOvershoot;
}

// Destructor
PIDController::~PIDController() {
}

//------------------------------------------------------------------------------
// Accessors
//------------------------------------------------------------------------------

double PIDController::getSetpoint() {
    return setpoint;
}

double PIDController::getKp() {
    return kp;
}

double PIDController::getKi() {
    return ki;
}

double PIDController::getKd() {
    return kd;
}

//------------------------------------------------------------------------------
// Mutators
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// targetSetpoint
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : setpoint
//
// This function sets the desired setpoint that the PID controller will
// attempt to track.
//------------------------------------------------------------------------------

void PIDController::targetSetpoint(double setpoint) {
    this->setpoint = limiter(setpoint, lowerInputLimit, upperInputLimit);
    peakTime = -1;
    settlingTime = -1;
    percentOvershoot = 0;
    sample_timer.start();
    performance_timer.start();
}

//------------------------------------------------------------------------------
// setGains
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : kp, ki, kd
//
// This function sets the control gains of the PID controller in order to
// achieve the desired performance characteristics.
//------------------------------------------------------------------------------

void PIDController::setGains(double kp, double ki, double kd) {
    this->kp = kp;
    this->ki = ki;
    this->kd = kd;
}

//------------------------------------------------------------------------------
// setInputLimits
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : lowerInputLimit, upperInputLimit
//
// This function allows the user to set bounds on the setpoint to prevent
// undesirable behavior of the system.
//------------------------------------------------------------------------------

void PIDController::setInputLimits(double lowerInputLimit, double upperInputLimit) {
    this->lowerInputLimit = lowerInputLimit;
    this->upperInputLimit = upperInputLimit;
}

//------------------------------------------------------------------------------
// setOutputLimits
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : lowerOutputLimit, upperOutputLimit
//
// This function allows to user to set bounds on the control variable to prevent
// undesirable behavior of the system.
//------------------------------------------------------------------------------

void PIDController::setOutputLimits(double lowerOutputLimit, double upperOutputLimit) {
    this->lowerOutputLimit = lowerOutputLimit;
    this->upperOutputLimit = upperOutputLimit;
}

double PIDController::limiter(double value, double lowerLimit, double upperLimit) {
    if (lowerLimit == upperLimit) {
        return value;
    }
    else if(value < lowerLimit) {
        return lowerLimit;
    }
    else if(value > upperLimit) {
        return upperLimit;
    }
    else
        return value;
}

void PIDController::reset() {
    setpoint = 0;
    integrator = 0;
    lastError = 0;
    peakTime = -1;
    settlingTime = -1;
    percentOvershoot = 0;
    sample_timer.stop();
    performance_timer.stop();
}

bool PIDController::hasSettled() {
    if(settlingTime != -1) {
        return true;
    }

    else {
        return false;
    }
}

double PIDController::calc(double processVariable) {
    sample_timer.stop();

    double percent = (processVariable/setpoint) - 1;

    if(percent > percentOvershoot && percent > 0)
    {
        percentOvershoot = processVariable/setpoint;
        peakTime = (performance_timer.elapsed().wall)/1e9;
    }
    if(abs(percent) < 0.05 && settlingTime == -1)
    {
        performance_timer.stop();
        settlingTime = (performance_timer.elapsed().wall)/1e9;
        std::cout << "Peak Time Tp: " << peakTime << std::endl;
        std::cout << "Percent Overshoot %OS: " << percentOvershoot << std::endl;
        std::cout << "Settling Time Ts" << settlingTime << std::endl;
    }

    double error = setpoint - processVariable;
    double samplingTime = (sample_timer.elapsed().wall)/1e9;
    double differentiator = (error - lastError)/samplingTime;
    integrator += (error * samplingTime);
    double controlVariable = kp * error + ki * integrator + kd * differentiator;

    controlVariable = limiter(controlVariable, lowerOutputLimit, upperOutputLimit);

    lastError = error;
    sample_timer.start();

    return controlVariable;
}
<commit_msg>Finish adding member function comments<commit_after>//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------

#include "PIDController.h"

//------------------------------------------------------------------------------
// Constructors
//------------------------------------------------------------------------------

// Default constructor
PIDController::PIDController() {
    this->setGains(0, 0, 0);
    this->setInputLimits(-1, -1);
    this->setOutputLimits(-1, -1);
    this->reset();
}

// Just gains, no limits
PIDController::PIDController(double kp, double ki, double kd) {
    this->setGains(kp, ki, kd);
    this->setInputLimits(-1, -1);
    this->setOutputLimits(-1, -1);
    this->reset();
}
// Gains and output limits
PIDController::PIDController(double kp, double ki, double kd, double lowerOutputLimit, double upperOutputLimit) {
    this->setGains(kp, ki, kd);
    this->setInputLimits(-1, -1);
    this->setOutputLimits(lowerOutputLimit, upperOutputLimit);
    this->reset();
}

// All gains and limits
PIDController::PIDController(double kp, double ki, double kd, double lowerInputLimit, double upperInputLimit, double lowerOutputLimit, double upperOutputLimit) {
    this->setGains(kp, ki, kd);
    this->setInputLimits(lowerInputLimit, upperInputLimit);
    this->setOutputLimits(lowerOutputLimit, upperOutputLimit);
    this->reset();
}

// Copy constructor
PIDController::PIDController(const PIDController& orig) {
    this->setGains(orig.kp, orig.ki, orig.kd);
    this->setInputLimits(orig.lowerInputLimit, orig.upperInputLimit);
    this->setOutputLimits(orig.lowerOutputLimit, orig.lowerInputLimit);
    integrator = orig.integrator;
    lastError = orig.lastError;
    peakTime = orig.peakTime;
    settlingTime = orig.settlingTime;
    percentOvershoot = orig.percentOvershoot;
}

// Destructor
PIDController::~PIDController() {
}

//------------------------------------------------------------------------------
// Accessors
//------------------------------------------------------------------------------

double PIDController::getSetpoint() {
    return setpoint;
}

double PIDController::getKp() {
    return kp;
}

double PIDController::getKi() {
    return ki;
}

double PIDController::getKd() {
    return kd;
}

//------------------------------------------------------------------------------
// Mutators
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// targetSetpoint
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : setpoint
//
// This function sets the desired setpoint that the PID controller will
// attempt to track.
//------------------------------------------------------------------------------

void PIDController::targetSetpoint(double setpoint) {
    this->setpoint = limiter(setpoint, lowerInputLimit, upperInputLimit);
    peakTime = -1;
    settlingTime = -1;
    percentOvershoot = 0;
    sample_timer.start();
    performance_timer.start();
}

//------------------------------------------------------------------------------
// setGains
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : kp, ki, kd
//
// This function sets the control gains of the PID controller in order to
// achieve the desired performance characteristics.
//------------------------------------------------------------------------------

void PIDController::setGains(double kp, double ki, double kd) {
    this->kp = kp;
    this->ki = ki;
    this->kd = kd;
}

//------------------------------------------------------------------------------
// setInputLimits
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : lowerInputLimit, upperInputLimit
//
// This function allows the user to set bounds on the setpoint to prevent
// undesirable behavior of the system.
//------------------------------------------------------------------------------

void PIDController::setInputLimits(double lowerInputLimit, double upperInputLimit) {
    this->lowerInputLimit = lowerInputLimit;
    this->upperInputLimit = upperInputLimit;
}

//------------------------------------------------------------------------------
// setOutputLimits
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : lowerOutputLimit, upperOutputLimit
//
// This function allows the user to set bounds on the control variable to
// prevent undesirable behavior of the system.
//------------------------------------------------------------------------------

void PIDController::setOutputLimits(double lowerOutputLimit, double upperOutputLimit) {
    this->lowerOutputLimit = lowerOutputLimit;
    this->upperOutputLimit = upperOutputLimit;
}

//------------------------------------------------------------------------------
// Other Functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// limiter
//------------------------------------------------------------------------------
//
// Return Value : double
// Parameters   : value, lowerLimit, upperLimit
//
// This function compares the input 'value' to the specified limits. If the
// value exceeds the limits, the value is capped to one of the limits.
//------------------------------------------------------------------------------

double PIDController::limiter(double value, double lowerLimit, double upperLimit) {
    if (lowerLimit == upperLimit) {
        return value;
    }
    else if(value < lowerLimit) {
        return lowerLimit;
    }
    else if(value > upperLimit) {
        return upperLimit;
    }
    else
        return value;
}

//------------------------------------------------------------------------------
// reset
//------------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// This function initializes the PID controller to the default values.
//------------------------------------------------------------------------------

void PIDController::reset() {
    setpoint = 0;
    integrator = 0;
    lastError = 0;
    peakTime = -1;
    settlingTime = -1;
    percentOvershoot = 0;
    sample_timer.stop();
    performance_timer.stop();
}

//------------------------------------------------------------------------------
// hasSettled
//------------------------------------------------------------------------------
//
// Return Value : bool
// Parameters   : None
//
// This function returns true only when the PID controller has stabilized to
// within 5% of its final value.
//------------------------------------------------------------------------------

bool PIDController::hasSettled() {
    if(settlingTime != -1) {
        return true;
    }

    else {
        return false;
    }
}

//------------------------------------------------------------------------------
// calc
//------------------------------------------------------------------------------
//
// Return Value : double
// Parameters   : processVariable
//
// This function calculates the next output value of the PID controller, given
// the current setpoint, elasped time, and feedback (processVariable). It also
// keeps track of peak time, settling time, and percent overshoot for quickly
// assessing the current performance of the controller.
//------------------------------------------------------------------------------

double PIDController::calc(double processVariable) {
    sample_timer.stop();

    double percent = (processVariable/setpoint) - 1;

    if(percent > percentOvershoot && percent > 0)
    {
        percentOvershoot = processVariable/setpoint;
        peakTime = (performance_timer.elapsed().wall)/1e9;
    }
    if(abs(percent) < 0.05 && settlingTime == -1)
    {
        performance_timer.stop();
        settlingTime = (performance_timer.elapsed().wall)/1e9;
        std::cout << "Peak Time Tp: " << peakTime << std::endl;
        std::cout << "Percent Overshoot %OS: " << percentOvershoot << std::endl;
        std::cout << "Settling Time Ts" << settlingTime << std::endl;
    }

    double error = setpoint - processVariable;
    double samplingTime = (sample_timer.elapsed().wall)/1e9;
    double differentiator = (error - lastError)/samplingTime;
    integrator += (error * samplingTime);
    double controlVariable = kp * error + ki * integrator + kd * differentiator;

    controlVariable = limiter(controlVariable, lowerOutputLimit, upperOutputLimit);

    lastError = error;
    sample_timer.start();

    return controlVariable;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: adminpages.hxx,v $
 *
 *  $Revision: 1.31 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 10:24: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
 *
 ************************************************************************/

#ifndef _DBAUI_ADMINPAGES_HXX_
#define _DBAUI_ADMINPAGES_HXX_

#ifndef _SFXTABDLG_HXX
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _DBAUI_DSNTYPES_HXX_
#include "dsntypes.hxx"
#endif
#ifndef _DBAUI_COMMON_TYPES_HXX_
#include "commontypes.hxx"
#endif
#ifndef _SVTOOLS_WIZARDMACHINE_HXX_
#include <svtools/wizardmachine.hxx>
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

class NumericField;
class Edit;
//.........................................................................
namespace dbaui
{
//.........................................................................
    /// helper class to wrap the savevalue and disable call
    class SAL_NO_VTABLE ISaveValueWrapper
    {
    public:
        virtual bool SaveValue() = 0;
        virtual bool Disable() = 0;
    };

    template < class T > class OSaveValueWrapper : public ISaveValueWrapper
    {
        T*  m_pSaveValue;
    public:
        OSaveValueWrapper(T* _pSaveValue) : m_pSaveValue(_pSaveValue)
        { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }

        virtual bool SaveValue() { m_pSaveValue->SaveValue(); return true;} // bool return value only for stl
        virtual bool Disable() { m_pSaveValue->Disable(); return true;} // bool return value only for stl
    };

    template < class T > class ODisableWrapper : public ISaveValueWrapper
    {
        T*  m_pSaveValue;
    public:
        ODisableWrapper(T* _pSaveValue) : m_pSaveValue(_pSaveValue)
        { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }

        virtual bool SaveValue() { return true;} // bool return value only for stl
        virtual bool Disable() { m_pSaveValue->Disable(); return true;} // bool return value only for stl
    };

    struct TSaveValueWrapperFunctor : public unary_function< ISaveValueWrapper, bool>
    {
        bool operator() (ISaveValueWrapper* lhs)
        {
            return lhs->SaveValue();
        }
    };
    struct TDisableWrapperFunctor : public unary_function< ISaveValueWrapper, bool>
    {
        bool operator() (ISaveValueWrapper* lhs)
        {
            return lhs->Disable();
        }
    };

    struct TDeleteWrapperFunctor : public unary_function< ISaveValueWrapper, bool>
    {
        bool operator() (ISaveValueWrapper* lhs)
        {
            delete lhs;
            return true;
        }
    };

    //=========================================================================
    //= OGenericAdministrationPage
    //=========================================================================
    class IDatabaseSettingsDialog;
    class IItemSetHelper;
    class OGenericAdministrationPage : public SfxTabPage, public svt::IWizardPage
    {
    private:
        Link            m_aModifiedHandler;     /// to be called if something on the page has been modified
        sal_Bool        m_abEnableRoadmap;
    protected:
        IDatabaseSettingsDialog*   m_pAdminDialog;
        IItemSetHelper* m_pItemSetHelper;
        FixedText*      m_pFT_HeaderText;

        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                            m_xORB;
    public:
        OGenericAdministrationPage(Window* _pParent, const ResId& _rId, const SfxItemSet& _rAttrSet);
        ~OGenericAdministrationPage();

        /// set a handler which gets called every time something on the page has been modified
        void SetModifiedHandler(const Link& _rHandler) { m_aModifiedHandler = _rHandler; }

        /** Sets the ParentDialog
            @param  _pAdminDialog
                the ParentDialog
            @param  _pItemSetHelper
                the itemset helper
        */
        inline void SetAdminDialog(IDatabaseSettingsDialog* _pDialog,IItemSetHelper* _pItemSetHelper)
        {
            OSL_ENSURE(_pDialog && _pItemSetHelper,"Values are NULL!");
            m_pAdminDialog = _pDialog;
            m_pItemSetHelper = _pItemSetHelper;
        }

        /** Sets the ServiceFactory
            @param  _rxORB
                The service factory.
        */
        virtual void SetServiceFactory(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > _rxORB)
        {
            m_xORB = _rxORB;
        }

        /** opens a dialog filled with all data sources available for this type and
            returns the selected on.
            @param  _eType
                The type for which the data source dialog should be opened.
            @param  _sReturn
                <OUT/> contains the selected name.
            @return
                <FALSE/> if an error occured, otherwise <TRUE/>
        */
        sal_Bool getSelectedDataSource(DATASOURCE_TYPE _eType,::rtl::OUString& _sReturn,::rtl::OUString& _sCurr);

        // svt::IWizardPage
        virtual void enableHeader( const Bitmap& _rBitmap, sal_Int32 _nPixelHeight, GrantAccess );
        virtual void initializePage();
        virtual sal_Bool commitPage(COMMIT_REASON _eReason);

        void                SetRoadmapStateValue( sal_Bool _bDoEnable ) { m_abEnableRoadmap = _bDoEnable; }
        bool                GetRoadmapStateValue() const { return m_abEnableRoadmap; }

    protected:
        /// default implementation: call FillItemSet, call prepareLeave,
        virtual int DeactivatePage(SfxItemSet* pSet);
        using SfxTabPage::DeactivatePage;
        /// default implementation: call implInitControls with the given item set and _bSaveValue = sal_False
        virtual void Reset(const SfxItemSet& _rCoreAttrs);
        /// default implementation: call implInitControls with the given item set and _bSaveValue = sal_True
        virtual void ActivatePage(const SfxItemSet& _rSet);

        // TabPage overridables
        virtual void    ActivatePage();

    protected:
        void callModifiedHdl() const { if (m_aModifiedHandler.IsSet()) m_aModifiedHandler.Call((void*)this); }

        /// called from within DeactivatePage. The page is allowed to be deactivated if this method returns sal_True
        virtual sal_Bool prepareLeave() { return sal_True; }

        /** called from within Reset and ActivatePage, use to initialize the controls with the items from the given set
            @param      _bSaveValue     if set to sal_True, the implementation should call SaveValue on all relevant controls
        */
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);

        /// analyze the invalid and the readonly flag which may be present in the set
        void getFlags(const SfxItemSet& _rSet, sal_Bool& _rValid, sal_Bool& _rReadonly);

        /** will be called inside <method>implInitControls</method> to save the value if necessary
            @param  _rControlList
                The list must be filled with the controls.
                It is not allowed to clear the list before pusching data into it.
        */
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList) = 0;

        /** will be called inside <method>implInitControls</method> to disable if necessary
            @param  _rControlList
                The list must be filled with the controls.
                It is not allowed to clear the list before pusching data into it.
        */
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList) = 0;

        /** fills the Boolean value into the item set when the value changed.
            @param  _rSet
                The item set where to put the new value into.
            @param  _pCheckBox
                The check box which is checked.
            @param  _nID
                The id in the itemset to set whith the new value.
            @param  _bChangedSomething
                <TRUE/> if something changed otherwise <FALSE/>
        */
        void fillBool(SfxItemSet& _rSet,CheckBox* _pCheckBox,USHORT _nID,sal_Bool& _bChangedSomething);

        /** fills the int value into the item set when the value changed.
            @param  _rSet
                The item set where to put the new value into.
            @param  _pEdit
                The check box which is checked.
            @param  _nID
                The id in the itemset to set whith the new value.
            @param  _bChangedSomething
                <TRUE/> if something changed otherwise <FALSE/>
        */
        void fillInt32(SfxItemSet& _rSet,NumericField* _pEdit,USHORT _nID,sal_Bool& _bChangedSomething);

        /** fills the String value into the item set when the value changed.
            @param  _rSet
                The item set where to put the new value into.
            @param  _pEdit
                The check box which is checked.
            @param  _nID
                The id in the itemset to set whith the new value.
            @param  _bChangedSomething
                <TRUE/> if something changed otherwise <FALSE/>
        */
        void fillString(SfxItemSet& _rSet,Edit* _pEdit,USHORT _nID,sal_Bool& _bChangedSomething);

        // used to set the right Pane header of a wizard to bold
        void SetControlFontWeight(Window* _pWindow, FontWeight _eWeight = WEIGHT_BOLD);
        void SetHeaderText( USHORT _nFTResId, USHORT _StringResId);

        Point MovePoint(Point _aPixelBasePoint, sal_Int32 _XShift, sal_Int32 _YShift);

    protected:
        /** This link be used for controls where the tabpage does not need to take any special action when the control
            is modified. The implementation just calls callModifiedHdl.
        */
        DECL_LINK(OnControlModified, Control*);
        DECL_LINK(OnTestConnectionClickHdl,PushButton*);

        /// may be used in SetXXXHdl calls to controls, is a link to <method>OnControlModified</method>
        virtual Link getControlModifiedLink() { return LINK(this, OGenericAdministrationPage, OnControlModified); }
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif // _DBAUI_ADMINPAGES_HXX_

<commit_msg>INTEGRATION: CWS dba24b (1.31.46); FILE MERGED 2007/08/27 10:49:13 fs 1.31.46.1: #i80930# _bRevertValue parameter to fillBool<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: adminpages.hxx,v $
 *
 *  $Revision: 1.32 $
 *
 *  last change: $Author: hr $ $Date: 2007-11-01 15:08:44 $
 *
 *  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 _DBAUI_ADMINPAGES_HXX_
#define _DBAUI_ADMINPAGES_HXX_

#ifndef _SFXTABDLG_HXX
#include <sfx2/tabdlg.hxx>
#endif
#ifndef _DBAUI_DSNTYPES_HXX_
#include "dsntypes.hxx"
#endif
#ifndef _DBAUI_COMMON_TYPES_HXX_
#include "commontypes.hxx"
#endif
#ifndef _SVTOOLS_WIZARDMACHINE_HXX_
#include <svtools/wizardmachine.hxx>
#endif
#ifndef _SV_FIELD_HXX
#include <vcl/field.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

class NumericField;
class Edit;
//.........................................................................
namespace dbaui
{
//.........................................................................
    /// helper class to wrap the savevalue and disable call
    class SAL_NO_VTABLE ISaveValueWrapper
    {
    public:
        virtual bool SaveValue() = 0;
        virtual bool Disable() = 0;
    };

    template < class T > class OSaveValueWrapper : public ISaveValueWrapper
    {
        T*  m_pSaveValue;
    public:
        OSaveValueWrapper(T* _pSaveValue) : m_pSaveValue(_pSaveValue)
        { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }

        virtual bool SaveValue() { m_pSaveValue->SaveValue(); return true;} // bool return value only for stl
        virtual bool Disable() { m_pSaveValue->Disable(); return true;} // bool return value only for stl
    };

    template < class T > class ODisableWrapper : public ISaveValueWrapper
    {
        T*  m_pSaveValue;
    public:
        ODisableWrapper(T* _pSaveValue) : m_pSaveValue(_pSaveValue)
        { OSL_ENSURE(m_pSaveValue,"Illegal argument!"); }

        virtual bool SaveValue() { return true;} // bool return value only for stl
        virtual bool Disable() { m_pSaveValue->Disable(); return true;} // bool return value only for stl
    };

    struct TSaveValueWrapperFunctor : public unary_function< ISaveValueWrapper, bool>
    {
        bool operator() (ISaveValueWrapper* lhs)
        {
            return lhs->SaveValue();
        }
    };
    struct TDisableWrapperFunctor : public unary_function< ISaveValueWrapper, bool>
    {
        bool operator() (ISaveValueWrapper* lhs)
        {
            return lhs->Disable();
        }
    };

    struct TDeleteWrapperFunctor : public unary_function< ISaveValueWrapper, bool>
    {
        bool operator() (ISaveValueWrapper* lhs)
        {
            delete lhs;
            return true;
        }
    };

    //=========================================================================
    //= OGenericAdministrationPage
    //=========================================================================
    class IDatabaseSettingsDialog;
    class IItemSetHelper;
    class OGenericAdministrationPage : public SfxTabPage, public svt::IWizardPage
    {
    private:
        Link            m_aModifiedHandler;     /// to be called if something on the page has been modified
        sal_Bool        m_abEnableRoadmap;
    protected:
        IDatabaseSettingsDialog*   m_pAdminDialog;
        IItemSetHelper* m_pItemSetHelper;
        FixedText*      m_pFT_HeaderText;

        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
                            m_xORB;
    public:
        OGenericAdministrationPage(Window* _pParent, const ResId& _rId, const SfxItemSet& _rAttrSet);
        ~OGenericAdministrationPage();

        /// set a handler which gets called every time something on the page has been modified
        void SetModifiedHandler(const Link& _rHandler) { m_aModifiedHandler = _rHandler; }

        /** Sets the ParentDialog
            @param  _pAdminDialog
                the ParentDialog
            @param  _pItemSetHelper
                the itemset helper
        */
        inline void SetAdminDialog(IDatabaseSettingsDialog* _pDialog,IItemSetHelper* _pItemSetHelper)
        {
            OSL_ENSURE(_pDialog && _pItemSetHelper,"Values are NULL!");
            m_pAdminDialog = _pDialog;
            m_pItemSetHelper = _pItemSetHelper;
        }

        /** Sets the ServiceFactory
            @param  _rxORB
                The service factory.
        */
        virtual void SetServiceFactory(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > _rxORB)
        {
            m_xORB = _rxORB;
        }

        /** opens a dialog filled with all data sources available for this type and
            returns the selected on.
            @param  _eType
                The type for which the data source dialog should be opened.
            @param  _sReturn
                <OUT/> contains the selected name.
            @return
                <FALSE/> if an error occured, otherwise <TRUE/>
        */
        sal_Bool getSelectedDataSource(DATASOURCE_TYPE _eType,::rtl::OUString& _sReturn,::rtl::OUString& _sCurr);

        // svt::IWizardPage
        virtual void enableHeader( const Bitmap& _rBitmap, sal_Int32 _nPixelHeight, GrantAccess );
        virtual void initializePage();
        virtual sal_Bool commitPage(COMMIT_REASON _eReason);

        void                SetRoadmapStateValue( sal_Bool _bDoEnable ) { m_abEnableRoadmap = _bDoEnable; }
        bool                GetRoadmapStateValue() const { return m_abEnableRoadmap; }

    protected:
        /// default implementation: call FillItemSet, call prepareLeave,
        virtual int DeactivatePage(SfxItemSet* pSet);
        using SfxTabPage::DeactivatePage;
        /// default implementation: call implInitControls with the given item set and _bSaveValue = sal_False
        virtual void Reset(const SfxItemSet& _rCoreAttrs);
        /// default implementation: call implInitControls with the given item set and _bSaveValue = sal_True
        virtual void ActivatePage(const SfxItemSet& _rSet);

        // TabPage overridables
        virtual void    ActivatePage();

    protected:
        void callModifiedHdl() const { if (m_aModifiedHandler.IsSet()) m_aModifiedHandler.Call((void*)this); }

        /// called from within DeactivatePage. The page is allowed to be deactivated if this method returns sal_True
        virtual sal_Bool prepareLeave() { return sal_True; }

        /** called from within Reset and ActivatePage, use to initialize the controls with the items from the given set
            @param      _bSaveValue     if set to sal_True, the implementation should call SaveValue on all relevant controls
        */
        virtual void implInitControls(const SfxItemSet& _rSet, sal_Bool _bSaveValue);

        /// analyze the invalid and the readonly flag which may be present in the set
        void getFlags(const SfxItemSet& _rSet, sal_Bool& _rValid, sal_Bool& _rReadonly);

        /** will be called inside <method>implInitControls</method> to save the value if necessary
            @param  _rControlList
                The list must be filled with the controls.
                It is not allowed to clear the list before pusching data into it.
        */
        virtual void fillControls(::std::vector< ISaveValueWrapper* >& _rControlList) = 0;

        /** will be called inside <method>implInitControls</method> to disable if necessary
            @param  _rControlList
                The list must be filled with the controls.
                It is not allowed to clear the list before pusching data into it.
        */
        virtual void fillWindows(::std::vector< ISaveValueWrapper* >& _rControlList) = 0;

        /** fills the Boolean value into the item set when the value changed.
            @param  _rSet
                The item set where to put the new value into.
            @param  _pCheckBox
                The check box which is checked.
            @param  _nID
                The id in the itemset to set whith the new value.
            @param  _bChangedSomething
                <TRUE/> if something changed otherwise <FALSE/>
            @param _bRevertValue
                set to <TRUE/> if the display value should be reverted before putting it into the set
        */
        void fillBool( SfxItemSet& _rSet, CheckBox* _pCheckBox, USHORT _nID, sal_Bool& _bChangedSomething, bool _bRevertValue = false);

        /** fills the int value into the item set when the value changed.
            @param  _rSet
                The item set where to put the new value into.
            @param  _pEdit
                The check box which is checked.
            @param  _nID
                The id in the itemset to set whith the new value.
            @param  _bChangedSomething
                <TRUE/> if something changed otherwise <FALSE/>
        */
        void fillInt32(SfxItemSet& _rSet,NumericField* _pEdit,USHORT _nID,sal_Bool& _bChangedSomething);

        /** fills the String value into the item set when the value changed.
            @param  _rSet
                The item set where to put the new value into.
            @param  _pEdit
                The check box which is checked.
            @param  _nID
                The id in the itemset to set whith the new value.
            @param  _bChangedSomething
                <TRUE/> if something changed otherwise <FALSE/>
        */
        void fillString(SfxItemSet& _rSet,Edit* _pEdit,USHORT _nID,sal_Bool& _bChangedSomething);

        // used to set the right Pane header of a wizard to bold
        void SetControlFontWeight(Window* _pWindow, FontWeight _eWeight = WEIGHT_BOLD);
        void SetHeaderText( USHORT _nFTResId, USHORT _StringResId);

        Point MovePoint(Point _aPixelBasePoint, sal_Int32 _XShift, sal_Int32 _YShift);

    protected:
        /** This link be used for controls where the tabpage does not need to take any special action when the control
            is modified. The implementation just calls callModifiedHdl.
        */
        DECL_LINK(OnControlModified, Control*);
        DECL_LINK(OnTestConnectionClickHdl,PushButton*);

        /// may be used in SetXXXHdl calls to controls, is a link to <method>OnControlModified</method>
        virtual Link getControlModifiedLink() { return LINK(this, OGenericAdministrationPage, OnControlModified); }
    };

//.........................................................................
}   // namespace dbaui
//.........................................................................

#endif // _DBAUI_ADMINPAGES_HXX_

<|endoftext|>


<commit_before>/*
*
*	Author: Philipp Zschoche, https://zschoche.org
*
*/
#ifndef __FILESYSTEM_HPP__
#define __FILESYSTEM_HPP__

#include "device_io.hpp"
#include <array>
namespace ext2 {

/*
 * implements the device concept
 */
template <typename Filesystem> class inode : public inode_base<typename Filesystem::device_type> {
      public:
	typedef Filesystem fs_type;

      private:
	fs_type *fs;

	uint32_t get_block_id(uint32_t block_index) const {
		if (block_index < 12) {
			// direct pointer
			return this->data.block_pointer_direct[block_index];
		} else if (block_index < 268) {
			block_index -= 12;
			uint32_t result;
			auto blockid = this->data.block_pointer_indirect[0];
			detail::read_from_device(*fs->device(), fs->to_address(blockid, block_index * sizeof(uint32_t)), result);
			return result;
		} else {
			throw "this is not ready yet";
			return 0; // TODO: implement
		}
	}

      public:
	inode(fs_type *fs, uint64_t offset) : inode_base<typename Filesystem::device_type>(fs->device(), offset), fs(fs) {}

	inline bool is_directory() const { return detail::has_flag(this->data.type, detail::directory); }
	inline bool is_regular_file() const { return detail::has_flag(this->data.type, detail::regular_file); }
	inline bool is_symbolic_link() const { return detail::has_flag(this->data.type, detail::symbolic_link); }
	inline uint64_t size() const {
		if (is_regular_file() && fs->large_files()) {
			return (static_cast<uint64_t>(this->data.dir_acl) << 32) | (this->data.size);
		} else {
			return this->data.size;
		}
	}

	void read(uint64_t offset, char *buffer, uint64_t length) {
		auto buffer_offset = 0;
		do {
			auto block_index = offset / fs->block_size();
			auto block_offset = offset % fs->block_size();
			auto block_length = std::min(fs->block_size() - block_offset, length);
			fs->device()->read(fs->to_address(get_block_id(block_index), block_offset), &buffer[buffer_offset], block_length);
			buffer_offset += block_length;
			offset += block_length;
			length -= block_length;
		} while (length > 0);
	}
	void write(uint64_t offset, const char *buffer, uint64_t length) {} // TODO: implement!

	inline fs_type *get_fs() { return fs; }
};
template <typename OStream, typename Inode> void read_inode_content(OStream &os, Inode& inode) {
		std::array<char, 255> buffer;
		auto offset = 0;
		const auto size = inode.size();
		do {
			auto length = std::min<uint64_t>(size - offset, buffer.size());
			inode.read(offset, buffer.data(), length);
			os << std::string(buffer.data(), length);
			offset += length;
		} while (offset < size);
	}

typedef std::vector<detail::directory_entry> directory_entry_list;

namespace inodes {
template <typename Filesystem> struct file : inode<Filesystem> {

	template <typename OStream> void read_full_file(OStream &os) {
		read_inode_content(os, *this);
	}
};
template <typename OStream, typename Filesystem> OStream &operator<<(OStream &os, file<Filesystem> &f) {
	f.read_full_file(os);
	return os;
}

template <typename Filesystem> struct character_device : inode<Filesystem> {};
template <typename Filesystem> struct block_device : inode<Filesystem> {};
template <typename Filesystem> struct fifo : inode<Filesystem> {};
template <typename Filesystem> struct symbolic_link : inode<Filesystem> {

	std::string get_target() {
		/* http://www.nongnu.org/ext2-doc/ext2.html#DEF-SYMBOLIC-LINKS */
		if(this->size() < 60) {
			const char* cstring = reinterpret_cast<char*>(&(this->data.block_pointer_direct[0]));
			std::string result(cstring, this->size());
			return result;
		}

		std::stringstream ss;
		read_inode_content(ss, *this);
		return ss.str();
	}
};

template <typename Filesystem> struct directory : inode<Filesystem> {

	directory_entry_list read_entrys() {
		auto offset = 0;
		directory_entry_list result;
		result.reserve(8);
		do {
			detail::directory_entry entry;
			detail::read_from_device(*this, offset, entry, 8);
			if (entry.inode_id == 0)
				break;
			offset += 8;
			entry.name.resize(entry.name_size);
			this->read(offset, const_cast<char *>(entry.name.c_str()), entry.name_size);
			offset += entry.size - 8;
			result.push_back(std::move(entry));
		} while (offset < this->size());
		return result;
	}

	void write_entrys(const directory_entry_list &entrys) {
		// TODO
	}
};
} /* namespace inodes */

template <typename Filesystem> inodes::directory<Filesystem> *to_directory(inode<Filesystem> *from) {
	if (from->is_directory())
		return static_cast<inodes::directory<Filesystem> *>(from);
	else
		return nullptr;
}
template <typename Filesystem> inodes::file<Filesystem> *to_file(inode<Filesystem> *from) {
	if (from->is_regular_file())
		return static_cast<inodes::file<Filesystem> *>(from);
	else
		return nullptr;
}

template <typename Filesystem> inodes::symbolic_link<Filesystem> *to_symbolic_link(inode<Filesystem> *from) {
	if (from->is_symbolic_link())
		return static_cast<inodes::symbolic_link<Filesystem> *>(from);
	else
		return nullptr;
}

typedef std::vector<std::pair<uint64_t, std::string *> > path;

template <typename OStream> OStream &operator<<(OStream &os, const path &p) {
	for (const auto &item : p) {
		os << '/' << *item.second;
	}
	return os;
}

template <typename Device> class filesystem {
      public:
	typedef typename superblock<Device>::device_type device_type;
	typedef inode<filesystem<Device> > inode_type;
	typedef inodes::directory<filesystem<Device> > directory_type;
	typedef inodes::file<filesystem<Device> > file_type;
	typedef group_descriptor_table<Device> gd_table_type;

      private:
	superblock<Device> super_block;
	gd_table_type gd_table;
	uint32_t blocksize;

      public:
	filesystem(Device &d, uint64_t superblock_offset = 1024) : super_block(d, superblock_offset) {}

	inline device_type *device() { return super_block.device(); }

	void load() {
		super_block.load();
		blocksize = super_block.data.block_size();
		gd_table = read_group_descriptor_table(super_block);
	}

	template <typename OStream> OStream &dump(OStream &os) const {
		super_block.data.dump(os);
		for (const auto &item : gd_table) {
			item.data.dump(os);
		}
		return os;
	}

	inode_type get_inode(uint32_t inodeid) {
		auto block_group_id = (inodeid - 1) / super_block.data.inodes_per_group;
		auto index = (inodeid - 1) % super_block.data.inodes_per_group;
		auto block_id = (index * super_block.data.inode_size) / block_size();
		auto block_offset = (index * super_block.data.inode_size) - (block_id * block_size());
		block_id += gd_table[block_group_id].data.address_inode_table;
		inode_type result(this, to_address(block_id, block_offset));
		result.load();
		return result;
	}

	inode_type get_root() { return get_inode(2); }

	inline uint64_t to_address(uint32_t blockid, uint32_t block_offset) const { return (blockid * block_size()) + block_offset; }
	inline bool large_files() const { return super_block.data.large_files(); }
	inline uint32_t block_size() const { return blocksize; }
};

template <typename Device> filesystem<Device> read_filesystem(Device &d) {
	filesystem<Device> result(d);
	result.load();
	return result;
}

} /* namespace ext2 */

#endif /* __FILESYSTEM_HPP__ */
<commit_msg>Added a type for paths<commit_after>/*
*
*	Author: Philipp Zschoche, https://zschoche.org
*
*/
#ifndef __FILESYSTEM_HPP__
#define __FILESYSTEM_HPP__

#include "device_io.hpp"
#include <array>
#include <boost/algorithm/string/split.hpp>
namespace ext2 {

/*
 * implements the device concept
 */
template <typename Filesystem> class inode : public inode_base<typename Filesystem::device_type> {
      public:
	typedef Filesystem fs_type;

      private:
	fs_type *fs;

	uint32_t get_block_id(uint32_t block_index) const {
		if (block_index < 12) {
			// direct pointer
			return this->data.block_pointer_direct[block_index];
		} else if (block_index < 268) {
			block_index -= 12;
			uint32_t result;
			auto blockid = this->data.block_pointer_indirect[0];
			detail::read_from_device(*fs->device(), fs->to_address(blockid, block_index * sizeof(uint32_t)), result);
			return result;
		} else {
			throw "this is not ready yet";
			return 0; // TODO: implement
		}
	}

      public:
	inode(fs_type *fs, uint64_t offset) : inode_base<typename Filesystem::device_type>(fs->device(), offset), fs(fs) {}

	inline bool is_directory() const { return detail::has_flag(this->data.type, detail::directory); }
	inline bool is_regular_file() const { return detail::has_flag(this->data.type, detail::regular_file); }
	inline bool is_symbolic_link() const { return detail::has_flag(this->data.type, detail::symbolic_link); }
	inline uint64_t size() const {
		if (is_regular_file() && fs->large_files()) {
			return (static_cast<uint64_t>(this->data.dir_acl) << 32) | (this->data.size);
		} else {
			return this->data.size;
		}
	}

	void read(uint64_t offset, char *buffer, uint64_t length) {
		auto buffer_offset = 0;
		do {
			auto block_index = offset / fs->block_size();
			auto block_offset = offset % fs->block_size();
			auto block_length = std::min(fs->block_size() - block_offset, length);
			fs->device()->read(fs->to_address(get_block_id(block_index), block_offset), &buffer[buffer_offset], block_length);
			buffer_offset += block_length;
			offset += block_length;
			length -= block_length;
		} while (length > 0);
	}
	void write(uint64_t offset, const char *buffer, uint64_t length) {} // TODO: implement!

	inline fs_type *get_fs() { return fs; }
};
template <typename OStream, typename Inode> void read_inode_content(OStream &os, Inode &inode) {
	std::array<char, 255> buffer;
	auto offset = 0;
	const auto size = inode.size();
	do {
		auto length = std::min<uint64_t>(size - offset, buffer.size());
		inode.read(offset, buffer.data(), length);
		os << std::string(buffer.data(), length);
		offset += length;
	} while (offset < size);
}

typedef std::vector<detail::directory_entry> directory_entry_list;

namespace inodes {
template <typename Filesystem> struct file : inode<Filesystem> {

	template <typename OStream> void read_full_file(OStream &os) { read_inode_content(os, *this); }
};
template <typename OStream, typename Filesystem> OStream &operator<<(OStream &os, file<Filesystem> &f) {
	f.read_full_file(os);
	return os;
}

template <typename Filesystem> struct character_device : inode<Filesystem> {};
template <typename Filesystem> struct block_device : inode<Filesystem> {};
template <typename Filesystem> struct fifo : inode<Filesystem> {};
template <typename Filesystem> struct symbolic_link : inode<Filesystem> {

	std::string get_target() {
		/* http://www.nongnu.org/ext2-doc/ext2.html#DEF-SYMBOLIC-LINKS */
		if (this->size() < 60) {
			const char *cstring = reinterpret_cast<char *>(&(this->data.block_pointer_direct[0]));
			std::string result(cstring, this->size());
			return result;
		}

		std::stringstream ss;
		read_inode_content(ss, *this);
		return ss.str();
	}
};

template <typename Filesystem> struct directory : inode<Filesystem> {

	directory_entry_list read_entrys() {
		auto offset = 0;
		directory_entry_list result;
		result.reserve(8);
		do {
			detail::directory_entry entry;
			detail::read_from_device(*this, offset, entry, 8);
			if (entry.inode_id == 0)
				break;
			offset += 8;
			entry.name.resize(entry.name_size);
			this->read(offset, const_cast<char *>(entry.name.c_str()), entry.name_size);
			offset += entry.size - 8;
			result.push_back(std::move(entry));
		} while (offset < this->size());
		return result;
	}

	void write_entrys(const directory_entry_list &entrys) {
		// TODO
	}
};
} /* namespace inodes */

template <typename Filesystem> inodes::directory<Filesystem> *to_directory(inode<Filesystem> *from) {
	if (from->is_directory())
		return static_cast<inodes::directory<Filesystem> *>(from);
	else
		return nullptr;
}
template <typename Filesystem> inodes::file<Filesystem> *to_file(inode<Filesystem> *from) {
	if (from->is_regular_file())
		return static_cast<inodes::file<Filesystem> *>(from);
	else
		return nullptr;
}

template <typename Filesystem> inodes::symbolic_link<Filesystem> *to_symbolic_link(inode<Filesystem> *from) {
	if (from->is_symbolic_link())
		return static_cast<inodes::symbolic_link<Filesystem> *>(from);
	else
		return nullptr;
}

struct path {
	// typedef boost::iterator_range<std::string::iterator> range_type;
	typedef std::vector<std::string> vec_type;
	std::string str;
	vec_type vec;

	inline bool is_relative() const { return !(!str.empty() && str[0] == '/'); }
};

inline path path_from_string(const std::string &p) {
	path result{p};
	if (result.str.size() > 3) {
		auto first = result.str.begin();
		auto last = --(result.str.end());
		if (*first == '/')
			first++;
		if (*last != '/')
			last++;
		auto range = boost::make_iterator_range(first, last);
		boost::split(result.vec, range, [](auto c) { return c == '/'; });
	}
	return result;
}

template <typename Device> class filesystem {
      public:
	typedef typename superblock<Device>::device_type device_type;
	typedef inode<filesystem<Device> > inode_type;
	typedef inodes::directory<filesystem<Device> > directory_type;
	typedef inodes::file<filesystem<Device> > file_type;
	typedef group_descriptor_table<Device> gd_table_type;

      private:
	superblock<Device> super_block;
	gd_table_type gd_table;
	uint32_t blocksize;

      public:
	filesystem(Device &d, uint64_t superblock_offset = 1024) : super_block(d, superblock_offset) {}

	inline device_type *device() { return super_block.device(); }

	void load() {
		super_block.load();
		blocksize = super_block.data.block_size();
		gd_table = read_group_descriptor_table(super_block);
	}

	template <typename OStream> OStream &dump(OStream &os) const {
		super_block.data.dump(os);
		for (const auto &item : gd_table) {
			item.data.dump(os);
		}
		return os;
	}

	inode_type get_inode(uint32_t inodeid) {
		auto block_group_id = (inodeid - 1) / super_block.data.inodes_per_group;
		auto index = (inodeid - 1) % super_block.data.inodes_per_group;
		auto block_id = (index * super_block.data.inode_size) / block_size();
		auto block_offset = (index * super_block.data.inode_size) - (block_id * block_size());
		block_id += gd_table[block_group_id].data.address_inode_table;
		inode_type result(this, to_address(block_id, block_offset));
		result.load();
		return result;
	}

	inode_type get_root() { return get_inode(2); }

	inline uint64_t to_address(uint32_t blockid, uint32_t block_offset) const { return (blockid * block_size()) + block_offset; }
	inline bool large_files() const { return super_block.data.large_files(); }
	inline uint32_t block_size() const { return blocksize; }
};

template <typename Device> filesystem<Device> read_filesystem(Device &d) {
	filesystem<Device> result(d);
	result.load();
	return result;
}

} /* namespace ext2 */

#endif /* __FILESYSTEM_HPP__ */
<|endoftext|>


<commit_before>#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QPainter>
#include <QPrinter>
#include <QImage>
#include <qgraphicseffect.h>

#include <copasi.h>

#include <qlayout/qlayoutscene.h>
#include <qlayout/qcopasieffect.h>
#include <qlayout/qlabelgraphicsitem.h>
#include <qlayout/qstyledgraphicsitem.h>
#include <qlayout/qconnectiongraphicsitem.h>
#include <qlayout/qrenderconverter.h>
#include <layout/CLayout.h>
#include <layout/CLGlyphs.h>
#include <layout/CLText.h>
#include <layout/CLReactionGlyph.h>
#include <layout/CLRenderResolver.h>
#include <layout/CLGlobalRenderInformation.h>
#include <layout/CListOfLayouts.h>
#include <layout/CLLocalRenderInformation.h>
#include <CopasiDataModel/CCopasiDataModel.h>

QLayoutScene::QLayoutScene(CLayout* layout, CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
  : QGraphicsScene()
  , mpLayout(layout)
  , mpRender(renderInformation)
  , mpResolver(NULL)
{
  initializeResolver(model, renderInformation);
}

void QLayoutScene::setLayout(CLayout *layout, CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
{
  mpLayout = layout;
  setRenderInformation(model, renderInformation);
}

void QLayoutScene::setRenderInformation(CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
{
  initializeResolver(model, renderInformation);
}

const CLayout* QLayoutScene::getCurrentLayout() const
{
  return mpLayout;
}

const CLRenderInformationBase* QLayoutScene::getCurrentRenderInfo() const
{
  return mpRender;
}

void QLayoutScene::saveToFile(const std::string& fileName, const std::string& fileType /*= "pdf"*/)
{
  if (fileType == "pdf")
  {
    QPrinter printer (QPrinter::HighResolution);
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setOutputFileName(fileName.c_str());
    QPainter painter(&printer);
    painter.setRenderHints(
      QPainter::Antialiasing |QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
    render(&painter, QRect(), itemsBoundingRect());
    painter.end();
  }
  else
  {
    const int scale = 2;
    QImage image(QSize(width()*scale, height()*scale), QImage::Format_ARGB32);
    QPainter painter(&image);
    painter.setRenderHints(
      QPainter::Antialiasing |QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
    render(&painter, image.rect(), itemsBoundingRect());
    painter.end();
    image.save(fileName.c_str(), fileType.c_str());
  }
}

void QLayoutScene::initializeResolver(CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
{
  if (model == NULL)
    return;

  if (renderInformation == NULL)
  {
    if (mpLayout != NULL && mpLayout->getListOfLocalRenderInformationObjects().size() > 0)
      mpRender = mpLayout->getListOfLocalRenderInformationObjects()[0];
    else if (model->getListOfLayouts()->getListOfGlobalRenderInformationObjects().size() > 0)
      mpRender = model->getListOfLayouts()->getListOfGlobalRenderInformationObjects()[0];
  }
  else
    mpRender = renderInformation;

  if (mpLayout == NULL || mpRender == NULL)
    return;

  CLLocalRenderInformation* local = dynamic_cast<CLLocalRenderInformation*>(mpRender);
  if (local != NULL)
    mpResolver = new CLRenderResolver(*local, mpLayout->getListOfLocalRenderInformationObjects(),   model->getListOfLayouts()->getListOfGlobalRenderInformationObjects());
  else
    mpResolver = new CLRenderResolver(*dynamic_cast<CLGlobalRenderInformation*>(mpRender), model->getListOfLayouts()->getListOfGlobalRenderInformationObjects());

}

void QLayoutScene::setResolver(const CLRenderResolver* resolver)
{
  mpResolver = resolver;
}

const CLRenderResolver* QLayoutScene::getResolver() const
{
  return mpResolver;
}

QLayoutScene::~QLayoutScene()
{
}

void QLayoutScene::recreate()
{
  fillFromLayout(mpLayout);
  invalidate();
}

void QLayoutScene::addGlyph(const CLGraphicalObject* go)
{
  if (go == NULL) return;

  const CLGlyphWithCurve* curveGlyph = dynamic_cast<const CLGlyphWithCurve*>(go);
  const CLReactionGlyph* reaction = dynamic_cast<const CLReactionGlyph*>(go);
  const CLTextGlyph* text = dynamic_cast<const CLTextGlyph*>(go);
  const CLGeneralGlyph* general = dynamic_cast<const CLGeneralGlyph*>(go);
  QGraphicsItem *item = NULL;
  if (curveGlyph != NULL)
  {
    if (curveGlyph->getCurve().getNumCurveSegments() > 0 || reaction != NULL || general != NULL)
     item = new QConnectionGraphicsItem(curveGlyph,
       mpResolver == NULL ? NULL : mpResolver);

  }
  else if (text != NULL)
  {
    item = new QLabelGraphicsItem(text, mpResolver == NULL ? NULL : mpResolver);
  }
  else
  {
    item = new QStyledGraphicsItem(go, mpResolver == NULL ? NULL : mpResolver);
  }

  if (item != NULL)
  {
    CCopasiObject* obj = go->getModelObject();
    if (obj != NULL && text == NULL)
    {
      item->setData(COPASI_OBJECT_CN, QString(obj->getCN().c_str()));
      mItems[obj->getCN()]= item;
    }
    addItem(item);
  }
}

QGraphicsItem* QLayoutScene::getItemFor(const std::string& cn)
{
  return mItems[cn];
}

void QLayoutScene::fillFromLayout(const CLayout* layout)
{
  if (layout == NULL) return;

  clear();
  mItems.clear();

  if (mpRender != NULL && mpResolver != NULL)
  {
      QRenderConverter::setBackground(this, mpRender->getBackgroundColor(), mpResolver);
  }

  const CCopasiVector<CLCompartmentGlyph> & comps = layout->getListOfCompartmentGlyphs();
  auto itComp = comps.begin();
  while (itComp != comps.end())
  {
    addGlyph(*itComp);
    ++itComp;
  }

  const CCopasiVector<CLReactionGlyph> & reactions = layout->getListOfReactionGlyphs();
  auto itReactions = reactions.begin();
  while (itReactions != reactions.end())
  {
    addGlyph(*itReactions);
    ++itReactions;
  }

  const CCopasiVector<CLMetabGlyph> & species = layout->getListOfMetaboliteGlyphs();
  auto itSpecies = species.begin();
  while (itSpecies != species.end())
  {
    addGlyph(*itSpecies);
    ++itSpecies;
  }

  const CCopasiVector<CLTextGlyph> & texts = layout->getListOfTextGlyphs();
  auto itTexts = texts.begin();
  while (itTexts != texts.end())
  {
    addGlyph(*itTexts);
    ++itTexts;
  }

  const CCopasiVector<CLGeneralGlyph> & list = layout->getListOfGeneralGlyphs();
  auto itList = list.begin();
  while (itList != list.end())
  {
    addGlyph(*itList);
    ++itList;
  }
}

void QLayoutScene::dragLeaveEvent ( QGraphicsSceneDragDropEvent * event )
{
	qDebug("dragLeaveEvent");
}
<commit_msg>- removed remaining auto keywords, since we are not using c++-11 elsewhere<commit_after>#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QPainter>
#include <QPrinter>
#include <QImage>
#include <qgraphicseffect.h>

#include <copasi.h>

#include <qlayout/qlayoutscene.h>
#include <qlayout/qcopasieffect.h>
#include <qlayout/qlabelgraphicsitem.h>
#include <qlayout/qstyledgraphicsitem.h>
#include <qlayout/qconnectiongraphicsitem.h>
#include <qlayout/qrenderconverter.h>
#include <layout/CLayout.h>
#include <layout/CLGlyphs.h>
#include <layout/CLText.h>
#include <layout/CLReactionGlyph.h>
#include <layout/CLRenderResolver.h>
#include <layout/CLGlobalRenderInformation.h>
#include <layout/CListOfLayouts.h>
#include <layout/CLLocalRenderInformation.h>
#include <CopasiDataModel/CCopasiDataModel.h>

QLayoutScene::QLayoutScene(CLayout* layout, CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
  : QGraphicsScene()
  , mpLayout(layout)
  , mpRender(renderInformation)
  , mpResolver(NULL)
{
  initializeResolver(model, renderInformation);
}

void QLayoutScene::setLayout(CLayout *layout, CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
{
  mpLayout = layout;
  setRenderInformation(model, renderInformation);
}

void QLayoutScene::setRenderInformation(CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
{
  initializeResolver(model, renderInformation);
}

const CLayout* QLayoutScene::getCurrentLayout() const
{
  return mpLayout;
}

const CLRenderInformationBase* QLayoutScene::getCurrentRenderInfo() const
{
  return mpRender;
}

void QLayoutScene::saveToFile(const std::string& fileName, const std::string& fileType /*= "pdf"*/)
{
  if (fileType == "pdf")
  {
    QPrinter printer (QPrinter::HighResolution);
    printer.setOutputFormat(QPrinter::PdfFormat);
    printer.setOutputFileName(fileName.c_str());
    QPainter painter(&printer);
    painter.setRenderHints(
      QPainter::Antialiasing |QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
    render(&painter, QRect(), itemsBoundingRect());
    painter.end();
  }
  else
  {
    const int scale = 2;
    QImage image(QSize(width()*scale, height()*scale), QImage::Format_ARGB32);
    QPainter painter(&image);
    painter.setRenderHints(
      QPainter::Antialiasing |QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
    render(&painter, image.rect(), itemsBoundingRect());
    painter.end();
    image.save(fileName.c_str(), fileType.c_str());
  }
}

void QLayoutScene::initializeResolver(CCopasiDataModel* model, CLRenderInformationBase* renderInformation)
{
  if (model == NULL)
    return;

  if (renderInformation == NULL)
  {
    if (mpLayout != NULL && mpLayout->getListOfLocalRenderInformationObjects().size() > 0)
      mpRender = mpLayout->getListOfLocalRenderInformationObjects()[0];
    else if (model->getListOfLayouts()->getListOfGlobalRenderInformationObjects().size() > 0)
      mpRender = model->getListOfLayouts()->getListOfGlobalRenderInformationObjects()[0];
  }
  else
    mpRender = renderInformation;

  if (mpLayout == NULL || mpRender == NULL)
    return;

  CLLocalRenderInformation* local = dynamic_cast<CLLocalRenderInformation*>(mpRender);
  if (local != NULL)
    mpResolver = new CLRenderResolver(*local, mpLayout->getListOfLocalRenderInformationObjects(),   model->getListOfLayouts()->getListOfGlobalRenderInformationObjects());
  else
    mpResolver = new CLRenderResolver(*dynamic_cast<CLGlobalRenderInformation*>(mpRender), model->getListOfLayouts()->getListOfGlobalRenderInformationObjects());

}

void QLayoutScene::setResolver(const CLRenderResolver* resolver)
{
  mpResolver = resolver;
}

const CLRenderResolver* QLayoutScene::getResolver() const
{
  return mpResolver;
}

QLayoutScene::~QLayoutScene()
{
}

void QLayoutScene::recreate()
{
  fillFromLayout(mpLayout);
  invalidate();
}

void QLayoutScene::addGlyph(const CLGraphicalObject* go)
{
  if (go == NULL) return;

  const CLGlyphWithCurve* curveGlyph = dynamic_cast<const CLGlyphWithCurve*>(go);
  const CLReactionGlyph* reaction = dynamic_cast<const CLReactionGlyph*>(go);
  const CLTextGlyph* text = dynamic_cast<const CLTextGlyph*>(go);
  const CLGeneralGlyph* general = dynamic_cast<const CLGeneralGlyph*>(go);
  QGraphicsItem *item = NULL;
  if (curveGlyph != NULL)
  {
    if (curveGlyph->getCurve().getNumCurveSegments() > 0 || reaction != NULL || general != NULL)
     item = new QConnectionGraphicsItem(curveGlyph,
       mpResolver == NULL ? NULL : mpResolver);

  }
  else if (text != NULL)
  {
    item = new QLabelGraphicsItem(text, mpResolver == NULL ? NULL : mpResolver);
  }
  else
  {
    item = new QStyledGraphicsItem(go, mpResolver == NULL ? NULL : mpResolver);
  }

  if (item != NULL)
  {
    CCopasiObject* obj = go->getModelObject();
    if (obj != NULL && text == NULL)
    {
      item->setData(COPASI_OBJECT_CN, QString(obj->getCN().c_str()));
      mItems[obj->getCN()]= item;
    }
    addItem(item);
  }
}

QGraphicsItem* QLayoutScene::getItemFor(const std::string& cn)
{
  return mItems[cn];
}

void QLayoutScene::fillFromLayout(const CLayout* layout)
{
  if (layout == NULL) return;

  clear();
  mItems.clear();

  if (mpRender != NULL && mpResolver != NULL)
  {
      QRenderConverter::setBackground(this, mpRender->getBackgroundColor(), mpResolver);
  }

  const CCopasiVector<CLCompartmentGlyph> & comps = layout->getListOfCompartmentGlyphs();
  CCopasiVector<CLCompartmentGlyph>::const_iterator itComp = comps.begin();
  while (itComp != comps.end())
  {
    addGlyph(*itComp);
    ++itComp;
  }

  const CCopasiVector<CLReactionGlyph> & reactions = layout->getListOfReactionGlyphs();
  CCopasiVector<CLReactionGlyph>::const_iterator itReactions = reactions.begin();
  while (itReactions != reactions.end())
  {
    addGlyph(*itReactions);
    ++itReactions;
  }

  const CCopasiVector<CLMetabGlyph> & species = layout->getListOfMetaboliteGlyphs();
  CCopasiVector<CLMetabGlyph>::const_iterator itSpecies = species.begin();
  while (itSpecies != species.end())
  {
    addGlyph(*itSpecies);
    ++itSpecies;
  }

  const CCopasiVector<CLTextGlyph> & texts = layout->getListOfTextGlyphs();
  CCopasiVector<CLTextGlyph>::const_iterator itTexts = texts.begin();
  while (itTexts != texts.end())
  {
    addGlyph(*itTexts);
    ++itTexts;
  }

  const CCopasiVector<CLGeneralGlyph> & list = layout->getListOfGeneralGlyphs();
  CCopasiVector<CLGeneralGlyph>::const_iterator itList = list.begin();
  while (itList != list.end())
  {
    addGlyph(*itList);
    ++itList;
  }
}

void QLayoutScene::dragLeaveEvent ( QGraphicsSceneDragDropEvent * event )
{
	qDebug("dragLeaveEvent");
}
<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CTableCell.cpp,v $
   $Revision: 1.1 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/09/23 18:59:12 $
   End CVS Header */

#include <limits>
 #include <iostream>
 #include <sstream>

#include "copasi.h"

#include "CTableCell.h"

CTableCell::CTableCell(const char & separator):
    mSeparator(separator),
    mName(""),
    mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
    mIsValue(false)
{}

CTableCell::CTableCell(const CTableCell & src):
    mSeparator(src.mSeparator),
    mName(src.mName),
    mValue(src.mValue),
    mIsValue(src.mIsValue)
{}

CTableCell::~CTableCell();

bool CTableCell::setSeparator(const char & separator)
{
  mSeparator = separator;
  return true;
}

const char & CTableCell::getSeparator() const {return mSeparator;}

const bool & CTableCell::isValue() const {return mIsValue;}

const std::string & CTableCell::getName() const {return mName;}

const C_FLOAT64 & CTableCell::getValue() const {return mValue;}

#ifdef WIN32
// warning C4056: overflow in floating-point constant arithmetic
// warning C4756: overflow in constant arithmetic
# pragma warning (disable: 4056 4756)
 #endif

std::istream & operator >> (std::istream &is, CTableCell & cell)
{
  static char buffer[256];

  cell.mName = "";

  do
    {
      is.getline(buffer, 256, cell.mSeparator);
      cell.mName += buffer;
    }
  while (strlen(buffer) == 255 && !is.fail());

  /* Trim leading and trailing whitespaces from the string */
  std::string::size_type begin = cell.mName.find_first_not_of("\x20\x09\x0d\x0a");

  if (begin == std::string::npos)
    {
      cell.mName = "";
      cell.mIsValue = false;
      cell.mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      return is;
    }
  else
    {
      std::string::size_type end = cell.mName.find_last_not_of("\x20\x09\x0d\x0a");

      if (end == std::string::npos)
        cell.mName = cell.mName.substr(begin);
      else
        cell.mName = cell.mName.substr(begin, end - begin + 1);
    }

  /* Try to convert the string into a number */
  char * Tail;
  cell.mValue = strtod(cell.mName.c_str(), & Tail);

  if (!*Tail)
    {
      cell.mIsValue = true;
    }
  else if (cell.mName.c_str() == "INF")
    {
      cell.mIsValue = true;
      cell.mValue = DBL_MAX * 2;
    }
  else if (cell.mName.c_str() == "-INF")
    {
      cell.mIsValue = true;
      cell.mValue = - DBL_MAX * 2;
    }
  else
    {
      cell.mIsValue = false;
      cell.mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();
    }

  return is;
}

#ifdef WIN32
 # pragma warning (default: 4056 4756)
 #endif

CTableRow::CTableRow(const unsigned C_INT32 & size,
                     const char & separator):
    mCells(0),
    mSeparator(separator)
{resize(size);}

CTableRow::CTableRow(const CTableRow & src):
    mCells(src.mCells),
    mSeparator(src.mSeparator)
{}

CTableRow::~CTableRow() {}

const std::vector< CTableCell > & CTableRow::getCells() const
  {return mCells;}

bool CTableRow::resize(const unsigned C_INT32 & size)
{
  mCells.resize(size);

  std::vector< CTableCell >::iterator it = mCells.begin();
  std::vector< CTableCell >::iterator end = mCells.end();

  for (; it != end; ++it)
    it->setSeparator(mSeparator);

  return true;
}

const unsigned C_INT32 CTableRow::size() const
{return mCells.size();}

std::istream & operator >> (std::istream &is, CTableRow & row)
{
  std::stringstream line;

  is.get(*line.rdbuf(), '\x0a');
  is.ignore(1);

  std::vector< CTableCell >::iterator it = row.mCells.begin();
  std::vector< CTableCell >::iterator end = row.mCells.end();

  for (; it != end && !line.fail(); ++it)
    line >> *it;

  if (it == end) return is;

  CTableCell Unread(row.mSeparator);
  for (; it != end; ++it)
    *it = Unread;

  return is;
}
<commit_msg>Fixed missing inlcude.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/utilities/CTableCell.cpp,v $
   $Revision: 1.2 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/09/23 19:08:21 $
   End CVS Header */

#include <limits>
#include <iostream>
#include <sstream>
#include <float.h>

#include "copasi.h"

#include "CTableCell.h"

CTableCell::CTableCell(const char & separator):
    mSeparator(separator),
    mName(""),
    mValue(std::numeric_limits<C_FLOAT64>::quiet_NaN()),
    mIsValue(false)
{}

CTableCell::CTableCell(const CTableCell & src):
    mSeparator(src.mSeparator),
    mName(src.mName),
    mValue(src.mValue),
    mIsValue(src.mIsValue)
{}

CTableCell::~CTableCell() {}

bool CTableCell::setSeparator(const char & separator)
{
  mSeparator = separator;
  return true;
}

const char & CTableCell::getSeparator() const {return mSeparator;}

const bool & CTableCell::isValue() const {return mIsValue;}

const std::string & CTableCell::getName() const {return mName;}

const C_FLOAT64 & CTableCell::getValue() const {return mValue;}

#ifdef WIN32
// warning C4056: overflow in floating-point constant arithmetic
// warning C4756: overflow in constant arithmetic
# pragma warning (disable: 4056 4756)
 #endif

std::istream & operator >> (std::istream &is, CTableCell & cell)
{
  static char buffer[256];

  cell.mName = "";

  do
    {
      is.getline(buffer, 256, cell.mSeparator);
      cell.mName += buffer;
    }
  while (strlen(buffer) == 255 && !is.fail());

  /* Trim leading and trailing whitespaces from the string */
  std::string::size_type begin = cell.mName.find_first_not_of("\x20\x09\x0d\x0a");

  if (begin == std::string::npos)
    {
      cell.mName = "";
      cell.mIsValue = false;
      cell.mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();

      return is;
    }
  else
    {
      std::string::size_type end = cell.mName.find_last_not_of("\x20\x09\x0d\x0a");

      if (end == std::string::npos)
        cell.mName = cell.mName.substr(begin);
      else
        cell.mName = cell.mName.substr(begin, end - begin + 1);
    }

  /* Try to convert the string into a number */
  char * Tail;
  cell.mValue = strtod(cell.mName.c_str(), & Tail);

  if (!*Tail)
    {
      cell.mIsValue = true;
    }
  else if (cell.mName.c_str() == "INF")
    {
      cell.mIsValue = true;
      cell.mValue = DBL_MAX * 2;
    }
  else if (cell.mName.c_str() == "-INF")
    {
      cell.mIsValue = true;
      cell.mValue = - DBL_MAX * 2;
    }
  else
    {
      cell.mIsValue = false;
      cell.mValue = std::numeric_limits<C_FLOAT64>::quiet_NaN();
    }

  return is;
}

#ifdef WIN32
 # pragma warning (default: 4056 4756)
 #endif

CTableRow::CTableRow(const unsigned C_INT32 & size,
                     const char & separator):
    mCells(0),
    mSeparator(separator)
{resize(size);}

CTableRow::CTableRow(const CTableRow & src):
    mCells(src.mCells),
    mSeparator(src.mSeparator)
{}

CTableRow::~CTableRow() {}

const std::vector< CTableCell > & CTableRow::getCells() const
  {return mCells;}

bool CTableRow::resize(const unsigned C_INT32 & size)
{
  mCells.resize(size);

  std::vector< CTableCell >::iterator it = mCells.begin();
  std::vector< CTableCell >::iterator end = mCells.end();

  for (; it != end; ++it)
    it->setSeparator(mSeparator);

  return true;
}

const unsigned C_INT32 CTableRow::size() const
{return mCells.size();}

std::istream & operator >> (std::istream &is, CTableRow & row)
{
  std::stringstream line;

  is.get(*line.rdbuf(), '\x0a');
  is.ignore(1);

  std::vector< CTableCell >::iterator it = row.mCells.begin();
  std::vector< CTableCell >::iterator end = row.mCells.end();

  for (; it != end && !line.fail(); ++it)
    line >> *it;

  if (it == end) return is;

  CTableCell Unread(row.mSeparator);
  for (; it != end; ++it)
    *it = Unread;

  return is;
}
<|endoftext|>