<commit_before>#ifndef GUARD_persistent_object_hpp
#define GUARD_persistent_object_hpp

#include "database_connection.hpp"
#include <jewel/decimal.hpp>
#include <jewel/optional.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <exception>
#include <stdexcept>
#include <string>

namespace sqloxx
{

/**
 * Class for creating objects persisted to a database. This
 * should be inherited by a derived class and the pure virtual
 * functions (and possibly non-pure virtual functions) provided with
 * definitions (or possibly redefinitions in the case of the non-pure
 * virtual functions).
 *
 * @todo Provide for atomicity of loading and saving (not just of
 * SQL execution, but of the actual alteration of the in-memory objects).
 * Go through all the client classes in phatbooks and ensure the
 * do_load... and do_save... functions in each are atomic with respect to
 * the in-memory objects, and conform to the restrictions detailed in the
 * PersistentObject API documentation. To do this, I need a non-throwing
 * swap for each of the derived classes.
 *
 * @todo Unit testing.
 */
class PersistentObject
{
public:

	typedef int Id;

	/**
	 * Create a PersistentObject that corresponds (or purports to correspond)
	 * to one that already exists in the database.
	 *
	 * @param p_database_connection database connection with
	 * which the PersistentObject is associated.
	 *
	 * @param p_id the id of the object as it exists in the database. This
	 * presumably will be, or correspond directly to, the primary key.
	 *
	 * Note that even if there is no corresponding object in the database for
	 * the given value p_id, this constructor will still proceed without
	 * complaint. The constructor does not actually perform any checks on the
	 * validity either of p_database_connection or of p_id.
	 *
	 * Exception safety: nothrow guarantee (though derived classes'
	 * constructors might, of course, throw).
	 */
	PersistentObject
	(	boost::shared_ptr<DatabaseConnection> p_database_connection,
		Id p_id
	);

	/**
	 * Create a PersistentObject that does \e not correspond to
	 * one that already exists in the database.
	 *
	 * @param p_database_connection database connection with which the
	 * PersistentObject is to be associated.
	 *
	 * Exception safety: nothrow guarantee (though derived classes'
	 * constructors might, of course, throw).
	 */
	explicit
	PersistentObject
	(	boost::shared_ptr<DatabaseConnection> p_database_connection
	);

	/**
	 * Destructor.
	 *
	 * Exception safety: nothrow guarantee.
	 */
	~PersistentObject();

	/**
	 * Calls the derived class's implementation
	 * of do_load_all, if the object is not already
	 * fully loaded. If the object does not have an id,
	 * then this function does nothing.
	 *
	 * In defining \e do_load_all, the derived class should throw an instance
	 * of std::exception (may be an instance of an exception class derived
	 * therefrom) in the event that the load fails. If this
	 * is adhered to, and do_load_all is implemented with the strong
	 * exception-safety guarantee, and do_load_all does not perform any
	 * write operations on the database, or have other side-effects, then the
	 * \e load function will itself provide the strong exception safety
	 * guarantee.
	 *
	 * Note the implementation is wrapped as a transaction
	 * by calls to begin_transaction and end_transaction
	 * methods of the DatabaseConnection.
	 *
	 * The following exceptions may be thrown regardless of how
	 * do_load_all is defined:
	 *
	 * @throws TransactionNestingException in the event that the maximum
	 * level of transaction nesting for the database connection has been
	 * reached. (This is extremely unlikely.) If this occurs \e before
	 * do_load_all is entered, the object will be as it was before the
	 * function was called.
	 *
	 * @throws InvalidConnection in the event that the database connection is
	 * invalid at the point the \e load function is entered. If this occurs,
	 * the object will be as it was before this function was called.
	 *
	 * Exception safety: depends on how the derived class defines \e
	 * do_load_all. See above.
	 */
	void load();

	/**
	 * Saves the state of the in-memory object to the
	 * database, overwriting the data in the database in the
	 * event of any conflict with the existing persisted data
	 * for this id. This is done by calling
	 * do_save_existing_partial (in the event the object is not
	 * fully loaded) or do_save_existing_all (in the event the object
	 * is fully loaded). The do_save_... functions should be defined in
	 * the derived class.
	 *
	 * Note the implementation is wrapped as a transaction
	 * by calls to begin_transaction and end_transaction
	 * methods of the DatabaseConnection.
	 *
	 * Exception safety: depends on the exception safety of
	 * do_save_existing_all and do_save_existing_partial. If these
	 * functions provide the strong guarantee, then so does
	 * \e save_existing.
	 */
	void save_existing();

	/**
	 * Saves the state of the in-memory object to the database,
	 * as an additional item, rather than overwriting existing
	 * data. The id assigned to the just-saved object is then
	 * recorded in the object in memory, and can be retrieved by
	 * calling id().
	 *
	 * In the body of this function, a call is made to the pure virtual
	 * function
	 * do_save_new_all, which must be defined in the derived
	 * class. (But note that the base class save_new takes care of assigning
	 * the id and also wraps the save operation as a SQL transaction by
	 * calling the begin_transaction and end_transaction methods of the
	 * DatabaseConnection.)
	 *
	 * The do_get_table_name function must also
	 * be defined in the derived class in order for this function
	 * to find an automatically generated id to assign to the object
	 * when saved. By default it is assumed that the id is an auto-
	 * incrementing integer primary key generated by SQLite. However this
	 * behaviour can be overridden by redefining the
	 * do_calculate_prospective_key function in the derived class.
	 *
	 * Exception safety: depends on the exception safety of
	 * \e do_save_new_all. Providing both do_save_new_all offers the strong
	 * guarantee, then so does \e save_new.
	 */
	void save_new();

	/**
	 * @returns the id of the object, if it has one.
	 *
	 * @throws jewel::UninitializedOptionalException if the object doesn't
	 * have an id.
	 */
	Id id() const;

protected:

	/**
	 * Copy constructor is deliberately protected. Copy construction does
	 * not make much semantic sense, as each instance of PersistentObject is
	 * supposed to represent a \e unique object in the database, with a
	 * unique id. However we provide it to derived classes, who may wish
	 * to use it in, for example, copy-and-swap operations.
	 *
	 * Exception safety: nothrow guarantee (though derived classes'
	 * copy constructors might, of course, throw).
	 */
	PersistentObject(PersistentObject const& rhs);

	/**
	 * Swap function. Does what you expect. This swaps the base part of
	 * the object only.
	 *
	 * Exception safety: nothrow guarantee
	 */
	void swap_base_internals(PersistentObject& rhs);

	/**
	 * @returns a boost::shared_ptr to the database connection with which
	 * this instance of PersistentObject is associated. This is where the
	 * object will be loaded from or saved to, as the case may be.
	 *
	 * Exception safety: nothrow guarantee
	 */
	boost::shared_ptr<DatabaseConnection> database_connection() const;

	/**
	 * Sets the id of this instance of PersistentObject to p_id.
	 *
	 * @param p_id the value to which you want to set the id of this object.
	 *
	 * Note an object that is created anew, that does not already exist
	 * in the database, should not have an id. By having an id, an object
	 * is saying "I exist in the database".
	 *
	 * Exception safety: nothrow guarantee.
	 */
	void set_id(Id p_id);

	/**
	 * @returns the id that would be assigned to the this instance of
	 * PersistentObject when saved to the database.
	 *
	 * This function calls /e do_calculate_prospective_key, which has a
	 * default implementation but may be redefined.
	 *
	 * @throws std::logic_error in the event this instance already has
	 * an id. (This occurs regardless of how/whether
	 * \e do_calculate_prospective_key is redefined.)
	 *
	 * Apart from \e std::logic_error as just described, the exception
	 * throwing behaviour and exception safety of this function depend on
	 * those of the function PersistentObject::do_calculate_prospective_key.
	 */
	Id prospective_key() const;

	/**
	 * @returns \e true if this instance of PersistentObject has
	 * an valid id; otherwise returns \e false.
	 *
	 * Exception safety: nothrow guarantee.
	 */
	bool has_id() const;

	/**
	 * The documentation for this function refers only to the
	 * default definition provided by PersistentObject.
	 *
	 * Provides an implementation for the public function prospective_key.
	 * Should not be called by any functions other than prospective_key.
	 *
	 * @throws sqloxx::TableSizeException if the greatest primary key value
	 * already in the table (i.e. the table into which this instance of
	 * PersistentObject would be persisted) is the maximum value for the
	 * type \e Id, so that another row could not be inserted without overflow.
	 *
	 * @throws sqloxx::DatabaseException, or a derivative therefrom, may
	 * be thrown if there is some other
	 * error finding the next primary key value. This should not occur except
	 * in the case of a corrupt database, or a memory allocation error
	 * (extremely unlikely), or the database connection being invalid
	 * (including because not yet connected to a database file).
	 * @throws sqloxx::InvalidConnection if the database connection
	 * associated with this instance of PersistentObject is invalid.
	 *
	 * Exception safety: strong guarantee.
	 */
	virtual Id do_calculate_prospective_key() const;

	/**
	 * See documentation for public \e load function.
	 *
	 * Exception safety: depends on function definition
	 * provided by derived class
	 */
	virtual void do_load_all() = 0;

	/**
	 * See documentation for public save_existing function.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual void do_save_existing_all() = 0;

	/**
	 * See documentation for public save_existing function.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual void do_save_existing_partial() = 0;

	/**
	 * See documentation for public save_new function.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual void do_save_new_all() = 0;

	/**
	 * This function should be defined in the derived class to return the
	 * name of the table in which instances of the derived class are stored
	 * in the database. This function is in turn called by the default
	 * implementation of \e do_calculate_prospective_key, which is in turn
	 * called by \e save_new.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual std::string do_get_table_name() const = 0;

private:

	/**
	 * Clears the loading status back to \e ghost.
	 *
	 * Exception safety: nothrow guarantee.
	 */
	void clear_loading_status();

	// Deliberately unimplemented. Assignment doesn't make much semantic
	// sense for a PersistentObject that is supposed to
	// represent a \e unique object in the database with a unique id.
	PersistentObject& operator=(PersistentObject const& rhs);

	enum LoadingStatus
	{
		ghost = 0,
		loading,
		loaded
	};

	// Data members

	boost::shared_ptr<DatabaseConnection> m_database_connection;
	boost::optional<Id> m_id;
	LoadingStatus m_loading_status;
};

}  // namespace sqloxx

#endif  // GUARD_persistent_object_hpp

<commit_msg>Updated a todo in persistent_object.hpp.<commit_after>#ifndef GUARD_persistent_object_hpp
#define GUARD_persistent_object_hpp

#include "database_connection.hpp"
#include <jewel/decimal.hpp>
#include <jewel/optional.hpp>
#include <boost/optional.hpp>
#include <boost/shared_ptr.hpp>
#include <exception>
#include <stdexcept>
#include <string>

namespace sqloxx
{

/**
 * Class for creating objects persisted to a database. This
 * should be inherited by a derived class and the pure virtual
 * functions (and possibly non-pure virtual functions) provided with
 * definitions (or possibly redefinitions in the case of the non-pure
 * virtual functions).
 *
 * @todo Provide for atomic saving (not just of
 * SQL execution, but of the actual alteration of the in-memory objects).
 * Go through all the client classes in Phatbooks and ensure the
 * do_save... functions in each are atomic with respect to
 * the in-memory objects, and conform to the restrictions detailed in the
 * PersistentObject API documentation. (Note I have already done this
 * for \e load functions.)
 *
 * @todo Unit testing.
 */
class PersistentObject
{
public:

	typedef int Id;

	/**
	 * Create a PersistentObject that corresponds (or purports to correspond)
	 * to one that already exists in the database.
	 *
	 * @param p_database_connection database connection with
	 * which the PersistentObject is associated.
	 *
	 * @param p_id the id of the object as it exists in the database. This
	 * presumably will be, or correspond directly to, the primary key.
	 *
	 * Note that even if there is no corresponding object in the database for
	 * the given value p_id, this constructor will still proceed without
	 * complaint. The constructor does not actually perform any checks on the
	 * validity either of p_database_connection or of p_id.
	 *
	 * Exception safety: nothrow guarantee (though derived classes'
	 * constructors might, of course, throw).
	 */
	PersistentObject
	(	boost::shared_ptr<DatabaseConnection> p_database_connection,
		Id p_id
	);

	/**
	 * Create a PersistentObject that does \e not correspond to
	 * one that already exists in the database.
	 *
	 * @param p_database_connection database connection with which the
	 * PersistentObject is to be associated.
	 *
	 * Exception safety: nothrow guarantee (though derived classes'
	 * constructors might, of course, throw).
	 */
	explicit
	PersistentObject
	(	boost::shared_ptr<DatabaseConnection> p_database_connection
	);

	/**
	 * Destructor.
	 *
	 * Exception safety: nothrow guarantee.
	 */
	~PersistentObject();

	/**
	 * Calls the derived class's implementation
	 * of do_load_all, if the object is not already
	 * fully loaded. If the object does not have an id,
	 * then this function does nothing.
	 *
	 * In defining \e do_load_all, the derived class should throw an instance
	 * of std::exception (may be an instance of an exception class derived
	 * therefrom) in the event that the load fails. If this
	 * is adhered to, and do_load_all is implemented with the strong
	 * exception-safety guarantee, and do_load_all does not perform any
	 * write operations on the database, or have other side-effects, then the
	 * \e load function will itself provide the strong exception safety
	 * guarantee.
	 *
	 * Note the implementation is wrapped as a transaction
	 * by calls to begin_transaction and end_transaction
	 * methods of the DatabaseConnection.
	 *
	 * The following exceptions may be thrown regardless of how
	 * do_load_all is defined:
	 *
	 * @throws TransactionNestingException in the event that the maximum
	 * level of transaction nesting for the database connection has been
	 * reached. (This is extremely unlikely.) If this occurs \e before
	 * do_load_all is entered, the object will be as it was before the
	 * function was called.
	 *
	 * @throws InvalidConnection in the event that the database connection is
	 * invalid at the point the \e load function is entered. If this occurs,
	 * the object will be as it was before this function was called.
	 *
	 * Exception safety: depends on how the derived class defines \e
	 * do_load_all. See above.
	 */
	void load();

	/**
	 * Saves the state of the in-memory object to the
	 * database, overwriting the data in the database in the
	 * event of any conflict with the existing persisted data
	 * for this id. This is done by calling
	 * do_save_existing_partial (in the event the object is not
	 * fully loaded) or do_save_existing_all (in the event the object
	 * is fully loaded). The do_save_... functions should be defined in
	 * the derived class.
	 *
	 * Note the implementation is wrapped as a transaction
	 * by calls to begin_transaction and end_transaction
	 * methods of the DatabaseConnection.
	 *
	 * Exception safety: depends on the exception safety of
	 * do_save_existing_all and do_save_existing_partial. If these
	 * functions provide the strong guarantee, then so does
	 * \e save_existing.
	 */
	void save_existing();

	/**
	 * Saves the state of the in-memory object to the database,
	 * as an additional item, rather than overwriting existing
	 * data. The id assigned to the just-saved object is then
	 * recorded in the object in memory, and can be retrieved by
	 * calling id().
	 *
	 * In the body of this function, a call is made to the pure virtual
	 * function
	 * do_save_new_all, which must be defined in the derived
	 * class. (But note that the base class save_new takes care of assigning
	 * the id and also wraps the save operation as a SQL transaction by
	 * calling the begin_transaction and end_transaction methods of the
	 * DatabaseConnection.)
	 *
	 * The do_get_table_name function must also
	 * be defined in the derived class in order for this function
	 * to find an automatically generated id to assign to the object
	 * when saved. By default it is assumed that the id is an auto-
	 * incrementing integer primary key generated by SQLite. However this
	 * behaviour can be overridden by redefining the
	 * do_calculate_prospective_key function in the derived class.
	 *
	 * Exception safety: depends on the exception safety of
	 * \e do_save_new_all. Providing both do_save_new_all offers the strong
	 * guarantee, then so does \e save_new.
	 */
	void save_new();

	/**
	 * @returns the id of the object, if it has one.
	 *
	 * @throws jewel::UninitializedOptionalException if the object doesn't
	 * have an id.
	 */
	Id id() const;

protected:

	/**
	 * Copy constructor is deliberately protected. Copy construction does
	 * not make much semantic sense, as each instance of PersistentObject is
	 * supposed to represent a \e unique object in the database, with a
	 * unique id. However we provide it to derived classes, who may wish
	 * to use it in, for example, copy-and-swap operations.
	 *
	 * Exception safety: nothrow guarantee (though derived classes'
	 * copy constructors might, of course, throw).
	 */
	PersistentObject(PersistentObject const& rhs);

	/**
	 * Swap function. Does what you expect. This swaps the base part of
	 * the object only.
	 *
	 * Exception safety: nothrow guarantee
	 */
	void swap_base_internals(PersistentObject& rhs);

	/**
	 * @returns a boost::shared_ptr to the database connection with which
	 * this instance of PersistentObject is associated. This is where the
	 * object will be loaded from or saved to, as the case may be.
	 *
	 * Exception safety: nothrow guarantee
	 */
	boost::shared_ptr<DatabaseConnection> database_connection() const;

	/**
	 * Sets the id of this instance of PersistentObject to p_id.
	 *
	 * @param p_id the value to which you want to set the id of this object.
	 *
	 * Note an object that is created anew, that does not already exist
	 * in the database, should not have an id. By having an id, an object
	 * is saying "I exist in the database".
	 *
	 * Exception safety: nothrow guarantee.
	 */
	void set_id(Id p_id);

	/**
	 * @returns the id that would be assigned to the this instance of
	 * PersistentObject when saved to the database.
	 *
	 * This function calls /e do_calculate_prospective_key, which has a
	 * default implementation but may be redefined.
	 *
	 * @throws std::logic_error in the event this instance already has
	 * an id. (This occurs regardless of how/whether
	 * \e do_calculate_prospective_key is redefined.)
	 *
	 * Apart from \e std::logic_error as just described, the exception
	 * throwing behaviour and exception safety of this function depend on
	 * those of the function PersistentObject::do_calculate_prospective_key.
	 */
	Id prospective_key() const;

	/**
	 * @returns \e true if this instance of PersistentObject has
	 * an valid id; otherwise returns \e false.
	 *
	 * Exception safety: nothrow guarantee.
	 */
	bool has_id() const;

	/**
	 * The documentation for this function refers only to the
	 * default definition provided by PersistentObject.
	 *
	 * Provides an implementation for the public function prospective_key.
	 * Should not be called by any functions other than prospective_key.
	 *
	 * @throws sqloxx::TableSizeException if the greatest primary key value
	 * already in the table (i.e. the table into which this instance of
	 * PersistentObject would be persisted) is the maximum value for the
	 * type \e Id, so that another row could not be inserted without overflow.
	 *
	 * @throws sqloxx::DatabaseException, or a derivative therefrom, may
	 * be thrown if there is some other
	 * error finding the next primary key value. This should not occur except
	 * in the case of a corrupt database, or a memory allocation error
	 * (extremely unlikely), or the database connection being invalid
	 * (including because not yet connected to a database file).
	 * @throws sqloxx::InvalidConnection if the database connection
	 * associated with this instance of PersistentObject is invalid.
	 *
	 * Exception safety: strong guarantee.
	 */
	virtual Id do_calculate_prospective_key() const;

	/**
	 * See documentation for public \e load function.
	 *
	 * Exception safety: depends on function definition
	 * provided by derived class
	 */
	virtual void do_load_all() = 0;

	/**
	 * See documentation for public save_existing function.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual void do_save_existing_all() = 0;

	/**
	 * See documentation for public save_existing function.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual void do_save_existing_partial() = 0;

	/**
	 * See documentation for public save_new function.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual void do_save_new_all() = 0;

	/**
	 * This function should be defined in the derived class to return the
	 * name of the table in which instances of the derived class are stored
	 * in the database. This function is in turn called by the default
	 * implementation of \e do_calculate_prospective_key, which is in turn
	 * called by \e save_new.
	 *
	 * Exception safety: depends on function definition provided by
	 * derived class.
	 */
	virtual std::string do_get_table_name() const = 0;

private:

	/**
	 * Clears the loading status back to \e ghost.
	 *
	 * Exception safety: nothrow guarantee.
	 */
	void clear_loading_status();

	// Deliberately unimplemented. Assignment doesn't make much semantic
	// sense for a PersistentObject that is supposed to
	// represent a \e unique object in the database with a unique id.
	PersistentObject& operator=(PersistentObject const& rhs);

	enum LoadingStatus
	{
		ghost = 0,
		loading,
		loaded
	};

	// Data members

	boost::shared_ptr<DatabaseConnection> m_database_connection;
	boost::optional<Id> m_id;
	LoadingStatus m_loading_status;
};

}  // namespace sqloxx

#endif  // GUARD_persistent_object_hpp

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xsecverify.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 17:24:16 $
 *
 *  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
 *
 ************************************************************************/

#include <xsecctl.hxx>
#include "xsecparser.hxx"

#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT
#include <tools/debug.hxx>
#endif

#include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
#include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
#include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxs = com::sun::star::xml::sax;

/* xml security framework components */
#define SIGNATUREVERIFIER_COMPONENT "com.sun.star.xml.crypto.sax.SignatureVerifier"

/* protected: for signature verify */
cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
    sal_Int32 nSecurityId)
{
    if ( m_nStatusOfSecurityComponents != INITIALIZED )
    {
        return NULL;
    }

    sal_Int32 nIdOfSignatureElementCollector;
    cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;

    nIdOfSignatureElementCollector =
        m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False);

    m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);

        /*
         * create a SignatureVerifier
         */
    xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >(
        mxMSF->createInstance(
            rtl::OUString::createFromAscii( SIGNATUREVERIFIER_COMPONENT )),
        cssu::UNO_QUERY);

    cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);

    cssu::Sequence<cssu::Any> args(5);
    args[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId));
    args[1] = cssu::makeAny(m_xSAXEventKeeper);
    args[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector));
    args[3] = cssu::makeAny(m_xSecurityContext);
    args[4] = cssu::makeAny(m_xXMLSignature);
    xInitialization->initialize(args);

    cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster >
        signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);

    signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this );

    cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster
        (m_xSAXEventKeeper,
        cssu::UNO_QUERY);

    xReferenceResolvedBroadcaster->addReferenceResolvedListener(
        nIdOfSignatureElementCollector,
        xReferenceResolvedListener);

    cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
    keyCollector->setKeyId(0);

    return xReferenceResolvedListener;
}

void XSecController::addSignature()
{
    cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener = NULL;
    sal_Int32 nSignatureId = 0;

    if (m_bVerifyCurrentSignature)
    {
        chainOn(true);
        xReferenceResolvedListener = prepareSignatureToRead( m_nReservedSignatureId );
        m_bVerifyCurrentSignature = false;
        nSignatureId = m_nReservedSignatureId;
    }

    InternalSignatureInformation isi( nSignatureId, xReferenceResolvedListener );
    m_vInternalSignatureInformations.push_back( isi );
}

void XSecController::addReference( const rtl::OUString& ouUri)
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE,ouUri, -1 );
}

void XSecController::addStreamReference(
    const rtl::OUString& ouUri,
    bool isBinary )
{
        sal_Int32 type = (isBinary?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE);

    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];

    if ( isi.xReferenceResolvedListener.is() )
    {
            /*
             * get the input stream
             */
            cssu::Reference< com::sun::star::io::XInputStream > xObjectInputStream
                = getObjectInputStream( ouUri );

        if ( xObjectInputStream.is() )
        {
            cssu::Reference<cssxc::XUriBinding> xUriBinding
                (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
            xUriBinding->setUriBinding(ouUri, xObjectInputStream);
        }
    }

    isi.addReference(type, ouUri, -1);
}

void XSecController::setReferenceCount() const
{
    const InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];

    if ( isi.xReferenceResolvedListener.is() )
    {
        const SignatureReferenceInformations &refInfors = isi.signatureInfor.vSignatureReferenceInfors;

        int refNum = refInfors.size();
        sal_Int32 referenceCount = 0;

        for(int i=0 ; i<refNum; ++i)
        {
            if (refInfors[i].nType == TYPE_SAMEDOCUMENT_REFERENCE )
            /*
             * same-document reference
             */
            {
                referenceCount++;
            }
        }

        cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
            (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
        xReferenceCollector->setReferenceCount( referenceCount );
    }
}

void XSecController::setX509IssuerName( rtl::OUString& ouX509IssuerName )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
}

void XSecController::setX509SerialNumber( rtl::OUString& ouX509SerialNumber )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
}

void XSecController::setX509Certificate( rtl::OUString& ouX509Certificate )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouX509Certificate = ouX509Certificate;
}

void XSecController::setSignatureValue( rtl::OUString& ouSignatureValue )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouSignatureValue = ouSignatureValue;
}

void XSecController::setDigestValue( rtl::OUString& ouDigestValue )
{
    SignatureInformation &si = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1].signatureInfor;
    SignatureReferenceInformation &reference = si.vSignatureReferenceInfors[si.vSignatureReferenceInfors.size()-1];
    reference.ouDigestValue = ouDigestValue;
}

void XSecController::setDate( rtl::OUString& ouDate )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    convertDateTime( isi.signatureInfor.stDateTime, ouDate );
}

/*
void XSecController::setTime( rtl::OUString& ouTime )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouTime = ouTime;
}
*/

void XSecController::setId( rtl::OUString& ouId )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouSignatureId = ouId;
}

void XSecController::setPropertyId( rtl::OUString& ouPropertyId )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouPropertyId = ouPropertyId;
}

/* public: for signature verify */
void XSecController::collectToVerify( const rtl::OUString& referenceId )
{
    /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */

    if ( m_nStatusOfSecurityComponents == INITIALIZED )
    /*
     * if all security components are ready, verify the signature.
     */
    {
        bool bJustChainingOn = false;
        cssu::Reference< cssxs::XDocumentHandler > xHandler = NULL;

        int i,j;
        int sigNum = m_vInternalSignatureInformations.size();

        for (i=0; i<sigNum; ++i)
        {
            InternalSignatureInformation& isi = m_vInternalSignatureInformations[i];
            SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors;
            int refNum = vReferenceInfors.size();

            for (j=0; j<refNum; ++j)
            {
                SignatureReferenceInformation &refInfor = vReferenceInfors[j];

                if (refInfor.ouURI == referenceId)
                {
                    if (chainOn(false))
                    {
                        bJustChainingOn = true;
                        xHandler = m_xSAXEventKeeper->setNextHandler(NULL);
                    }

                    sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
                        cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False );

                    cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster
                        (m_xSAXEventKeeper,
                        cssu::UNO_QUERY );

                    cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
                        ( isi.xReferenceResolvedListener, cssu::UNO_QUERY );

                    m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
                    xReferenceResolvedBroadcaster->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
                    xReferenceCollector->setReferenceId( nKeeperId );

                    isi.vKeeperIds[j] = nKeeperId;
                    break;
                }
            }
        }

        if ( bJustChainingOn )
        {
            cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY);
            if (m_xElementStackKeeper.is())
            {
                m_xElementStackKeeper->retrieve(xSEKHandler, sal_True);
            }
            m_xSAXEventKeeper->setNextHandler(xHandler);
        }
    }
}

void XSecController::addSignature( sal_Int32 nSignatureId )
{
    DBG_ASSERT( m_pXSecParser != NULL, "No XSecParser initialized" );

    m_nReservedSignatureId = nSignatureId;
    m_bVerifyCurrentSignature = true;
}

cssu::Reference< cssxs::XDocumentHandler > XSecController::createSignatureReader()
{
    m_pXSecParser = new XSecParser( this, NULL );
    cssu::Reference< cssl::XInitialization > xInitialization = m_pXSecParser;

    setSAXChainConnector(xInitialization, NULL, NULL);

    return m_pXSecParser;
}

void XSecController::releaseSignatureReader()
{
    clearSAXChainConnector( );
    m_pXSecParser = NULL;
}

<commit_msg>INTEGRATION: CWS jl32 (1.6.48); FILE MERGED 2006/03/21 12:12:30 jl 1.6.48.1: #i63427# removing a XML signature may break other signatures<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: xsecverify.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2006-04-07 11:57:46 $
 *
 *  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
 *
 ************************************************************************/

#include <xsecctl.hxx>
#include "xsecparser.hxx"

#ifndef _TOOLS_DEBUG_HXX //autogen wg. DBG_ASSERT
#include <tools/debug.hxx>
#endif

#include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
#include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
#include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
#include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxs = com::sun::star::xml::sax;

/* xml security framework components */
#define SIGNATUREVERIFIER_COMPONENT "com.sun.star.xml.crypto.sax.SignatureVerifier"

/* protected: for signature verify */
cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead(
    sal_Int32 nSecurityId)
{
    if ( m_nStatusOfSecurityComponents != INITIALIZED )
    {
        return NULL;
    }

    sal_Int32 nIdOfSignatureElementCollector;
    cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener;

    nIdOfSignatureElementCollector =
        m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False);

    m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId);

        /*
         * create a SignatureVerifier
         */
    xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >(
        mxMSF->createInstance(
            rtl::OUString::createFromAscii( SIGNATUREVERIFIER_COMPONENT )),
        cssu::UNO_QUERY);

    cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY);

    cssu::Sequence<cssu::Any> args(5);
    args[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId));
    args[1] = cssu::makeAny(m_xSAXEventKeeper);
    args[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector));
    args[3] = cssu::makeAny(m_xSecurityContext);
    args[4] = cssu::makeAny(m_xXMLSignature);
    xInitialization->initialize(args);

    cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster >
        signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY);

    signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this );

    cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster
        (m_xSAXEventKeeper,
        cssu::UNO_QUERY);

    xReferenceResolvedBroadcaster->addReferenceResolvedListener(
        nIdOfSignatureElementCollector,
        xReferenceResolvedListener);

    cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY);
    keyCollector->setKeyId(0);

    return xReferenceResolvedListener;
}

void XSecController::addSignature()
{
    cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener = NULL;
    sal_Int32 nSignatureId = 0;

    if (m_bVerifyCurrentSignature)
    {
        chainOn(true);
        xReferenceResolvedListener = prepareSignatureToRead( m_nReservedSignatureId );
        m_bVerifyCurrentSignature = false;
        nSignatureId = m_nReservedSignatureId;
    }

    InternalSignatureInformation isi( nSignatureId, xReferenceResolvedListener );
    m_vInternalSignatureInformations.push_back( isi );
}

void XSecController::addReference( const rtl::OUString& ouUri)
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE,ouUri, -1 );
}

void XSecController::addStreamReference(
    const rtl::OUString& ouUri,
    bool isBinary )
{
        sal_Int32 type = (isBinary?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE);

    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];

    if ( isi.xReferenceResolvedListener.is() )
    {
            /*
             * get the input stream
             */
            cssu::Reference< com::sun::star::io::XInputStream > xObjectInputStream
                = getObjectInputStream( ouUri );

        if ( xObjectInputStream.is() )
        {
            cssu::Reference<cssxc::XUriBinding> xUriBinding
                (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
            xUriBinding->setUriBinding(ouUri, xObjectInputStream);
        }
    }

    isi.addReference(type, ouUri, -1);
}

void XSecController::setReferenceCount() const
{
    const InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];

    if ( isi.xReferenceResolvedListener.is() )
    {
        const SignatureReferenceInformations &refInfors = isi.signatureInfor.vSignatureReferenceInfors;

        int refNum = refInfors.size();
        sal_Int32 referenceCount = 0;

        for(int i=0 ; i<refNum; ++i)
        {
            if (refInfors[i].nType == TYPE_SAMEDOCUMENT_REFERENCE )
            /*
             * same-document reference
             */
            {
                referenceCount++;
            }
        }

        cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
            (isi.xReferenceResolvedListener, cssu::UNO_QUERY);
        xReferenceCollector->setReferenceCount( referenceCount );
    }
}

void XSecController::setX509IssuerName( rtl::OUString& ouX509IssuerName )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
}

void XSecController::setX509SerialNumber( rtl::OUString& ouX509SerialNumber )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
}

void XSecController::setX509Certificate( rtl::OUString& ouX509Certificate )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouX509Certificate = ouX509Certificate;
}

void XSecController::setSignatureValue( rtl::OUString& ouSignatureValue )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouSignatureValue = ouSignatureValue;
}

void XSecController::setDigestValue( rtl::OUString& ouDigestValue )
{
    SignatureInformation &si = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1].signatureInfor;
    SignatureReferenceInformation &reference = si.vSignatureReferenceInfors[si.vSignatureReferenceInfors.size()-1];
    reference.ouDigestValue = ouDigestValue;
}

void XSecController::setDate( rtl::OUString& ouDate )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    convertDateTime( isi.signatureInfor.stDateTime, ouDate );
    isi.signatureInfor.ouDateTime = ouDate;
}

/*
void XSecController::setTime( rtl::OUString& ouTime )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouTime = ouTime;
}
*/

void XSecController::setId( rtl::OUString& ouId )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouSignatureId = ouId;
}

void XSecController::setPropertyId( rtl::OUString& ouPropertyId )
{
    InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
    isi.signatureInfor.ouPropertyId = ouPropertyId;
}

/* public: for signature verify */
void XSecController::collectToVerify( const rtl::OUString& referenceId )
{
    /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */

    if ( m_nStatusOfSecurityComponents == INITIALIZED )
    /*
     * if all security components are ready, verify the signature.
     */
    {
        bool bJustChainingOn = false;
        cssu::Reference< cssxs::XDocumentHandler > xHandler = NULL;

        int i,j;
        int sigNum = m_vInternalSignatureInformations.size();

        for (i=0; i<sigNum; ++i)
        {
            InternalSignatureInformation& isi = m_vInternalSignatureInformations[i];
            SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors;
            int refNum = vReferenceInfors.size();

            for (j=0; j<refNum; ++j)
            {
                SignatureReferenceInformation &refInfor = vReferenceInfors[j];

                if (refInfor.ouURI == referenceId)
                {
                    if (chainOn(false))
                    {
                        bJustChainingOn = true;
                        xHandler = m_xSAXEventKeeper->setNextHandler(NULL);
                    }

                    sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
                        cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False );

                    cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster
                        (m_xSAXEventKeeper,
                        cssu::UNO_QUERY );

                    cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
                        ( isi.xReferenceResolvedListener, cssu::UNO_QUERY );

                    m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
                    xReferenceResolvedBroadcaster->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
                    xReferenceCollector->setReferenceId( nKeeperId );

                    isi.vKeeperIds[j] = nKeeperId;
                    break;
                }
            }
        }

        if ( bJustChainingOn )
        {
            cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY);
            if (m_xElementStackKeeper.is())
            {
                m_xElementStackKeeper->retrieve(xSEKHandler, sal_True);
            }
            m_xSAXEventKeeper->setNextHandler(xHandler);
        }
    }
}

void XSecController::addSignature( sal_Int32 nSignatureId )
{
    DBG_ASSERT( m_pXSecParser != NULL, "No XSecParser initialized" );

    m_nReservedSignatureId = nSignatureId;
    m_bVerifyCurrentSignature = true;
}

cssu::Reference< cssxs::XDocumentHandler > XSecController::createSignatureReader()
{
    m_pXSecParser = new XSecParser( this, NULL );
    cssu::Reference< cssl::XInitialization > xInitialization = m_pXSecParser;

    setSAXChainConnector(xInitialization, NULL, NULL);

    return m_pXSecParser;
}

void XSecController::releaseSignatureReader()
{
    clearSAXChainConnector( );
    m_pXSecParser = NULL;
}

<|endoftext|>


<commit_before>#include "boundtextbox.h"

#include <boost/foreach.hpp>

#include <QIntValidator>
#include <QDoubleValidator>
#include <QKeyEvent>

BoundTextBox::BoundTextBox(QWidget *parent) :
	QLineEdit(parent)
{
	_integer = NULL;
	_integerArray = NULL;
	_number = NULL;

	//connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEditedHandler(QString)));
}

void BoundTextBox::bindTo(Option *option)
{
	_integer = dynamic_cast<OptionInteger *>(option);

	if (_integer != NULL)
	{
		this->setValidator(new QIntValidator(this));
		this->setText(QString::number(_integer->value()));
		return;
	}

	_integerArray = dynamic_cast<OptionIntegerArray *>(option);

	if (_integerArray != NULL)
	{
		this->setValidator(new QIntArrayValidator());
		return;
	}

	_number = dynamic_cast<OptionNumber *>(option);

	if (_number != NULL)
	{
		this->setValidator(new QDoubleValidator(_number->min(), _number->max(), 4, this));
		this->setText(QString::number(_number->value()));
		return;
	}

}

void BoundTextBox::keyPressEvent(QKeyEvent *event)
{
	QLineEdit::keyPressEvent(event);
	if (event->key() == Qt::Key_Return)
		finalise();
}

void BoundTextBox::focusOutEvent(QFocusEvent *event)
{
	QLineEdit::focusOutEvent(event);
	finalise();
}

void BoundTextBox::finalise()
{
	QString value = text();

	while (value.endsWith(","))
		value = value.left(value.length() - 1);

	if (_integerArray != NULL)
		_integerArray->setValue(QIntArrayValidator::parse(value));
	else if (_integer != NULL)
		_integer->setValue(value.toInt());
	else if (_number != NULL)
		_number->setValue(value.toDouble());
}

void BoundTextBox::textEditedHandler(QString text)
{
	this->validator()->fixup(text);
	setText(text);

	/*if (_integerArray != NULL)
		_integerArray->setValue(QIntArrayValidator::parse(text));
	else if (_integer != NULL)
		_integer->setValue(text.toInt());
	else if (_number != NULL)
		_number->setValue(text.toDouble());*/
}

BoundTextBox::QIntArrayValidator::QIntArrayValidator()
{
}

QValidator::State BoundTextBox::QIntArrayValidator::validate(QString &input, int &pos) const
{
	// this needs some TLC

	if (pos > input.length())
		pos = input.length();

	if (pos == 0 || input.at(pos-1) == ',')
		return QValidator::Intermediate;

	fixup(input);

	if (pos > input.size())
		pos = input.size();

	return QValidator::Acceptable;
}

void BoundTextBox::QIntArrayValidator::fixup(QString &input) const
{
	QString trimmed = input.trimmed();

	std::vector<int> array = parse(input);
	input = stringify(array);

	if (trimmed.length() > 0 && trimmed.at(trimmed.length() - 1) == ',')
		input = input + ",";
}

std::vector<int> BoundTextBox::QIntArrayValidator::parse(QString &input)
{
	input.replace(QString(" "), QString(","));

	std::vector<int> result;

	QStringList chunks = input.split(QChar(','), QString::SkipEmptyParts);

	BOOST_FOREACH(QString &chunk, chunks)
	{
		bool ok;
		int value = chunk.toInt(&ok);

		if (ok)
			result.push_back(value);
	}

	return result;
}

QString BoundTextBox::QIntArrayValidator::stringify(std::vector<int> &input)
{
	if (input.size() == 0)
		return QString();

	std::vector<int>::iterator itr = input.begin();

	QString result = QString::number(*itr);
	itr++;

	for (; itr != input.end(); itr++)
		result += QString(",%1").arg(*itr);

	return result;
}

<commit_msg>BoundTextBox now response to keypad enter<commit_after>#include "boundtextbox.h"

#include <boost/foreach.hpp>

#include <QIntValidator>
#include <QDoubleValidator>
#include <QKeyEvent>

BoundTextBox::BoundTextBox(QWidget *parent) :
	QLineEdit(parent)
{
	_integer = NULL;
	_integerArray = NULL;
	_number = NULL;

	//connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEditedHandler(QString)));
}

void BoundTextBox::bindTo(Option *option)
{
	_integer = dynamic_cast<OptionInteger *>(option);

	if (_integer != NULL)
	{
		this->setValidator(new QIntValidator(this));
		this->setText(QString::number(_integer->value()));
		return;
	}

	_integerArray = dynamic_cast<OptionIntegerArray *>(option);

	if (_integerArray != NULL)
	{
		this->setValidator(new QIntArrayValidator());
		return;
	}

	_number = dynamic_cast<OptionNumber *>(option);

	if (_number != NULL)
	{
		this->setValidator(new QDoubleValidator(_number->min(), _number->max(), 4, this));
		this->setText(QString::number(_number->value()));
		return;
	}

}

void BoundTextBox::keyPressEvent(QKeyEvent *event)
{
	QLineEdit::keyPressEvent(event);
	if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
		finalise();
}

void BoundTextBox::focusOutEvent(QFocusEvent *event)
{
	QLineEdit::focusOutEvent(event);
	finalise();
}

void BoundTextBox::finalise()
{
	QString value = text();

	while (value.endsWith(","))
		value = value.left(value.length() - 1);

	if (_integerArray != NULL)
		_integerArray->setValue(QIntArrayValidator::parse(value));
	else if (_integer != NULL)
		_integer->setValue(value.toInt());
	else if (_number != NULL)
		_number->setValue(value.toDouble());
}

void BoundTextBox::textEditedHandler(QString text)
{
	this->validator()->fixup(text);
	setText(text);

	/*if (_integerArray != NULL)
		_integerArray->setValue(QIntArrayValidator::parse(text));
	else if (_integer != NULL)
		_integer->setValue(text.toInt());
	else if (_number != NULL)
		_number->setValue(text.toDouble());*/
}

BoundTextBox::QIntArrayValidator::QIntArrayValidator()
{
}

QValidator::State BoundTextBox::QIntArrayValidator::validate(QString &input, int &pos) const
{
	// this needs some TLC

	if (pos > input.length())
		pos = input.length();

	if (pos == 0 || input.at(pos-1) == ',')
		return QValidator::Intermediate;

	fixup(input);

	if (pos > input.size())
		pos = input.size();

	return QValidator::Acceptable;
}

void BoundTextBox::QIntArrayValidator::fixup(QString &input) const
{
	QString trimmed = input.trimmed();

	std::vector<int> array = parse(input);
	input = stringify(array);

	if (trimmed.length() > 0 && trimmed.at(trimmed.length() - 1) == ',')
		input = input + ",";
}

std::vector<int> BoundTextBox::QIntArrayValidator::parse(QString &input)
{
	input.replace(QString(" "), QString(","));

	std::vector<int> result;

	QStringList chunks = input.split(QChar(','), QString::SkipEmptyParts);

	BOOST_FOREACH(QString &chunk, chunks)
	{
		bool ok;
		int value = chunk.toInt(&ok);

		if (ok)
			result.push_back(value);
	}

	return result;
}

QString BoundTextBox::QIntArrayValidator::stringify(std::vector<int> &input)
{
	if (input.size() == 0)
		return QString();

	std::vector<int>::iterator itr = input.begin();

	QString result = QString::number(*itr);
	itr++;

	for (; itr != input.end(); itr++)
		result += QString(",%1").arg(*itr);

	return result;
}

<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskExecutor.cpp
 */

#include "JPetTaskExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskExecutor::JPetTaskExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fProcessedFile(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskExecutor");
  }
}

bool JPetTaskExecutor::process()
{
  if(!processFromCmdLineArgs(fProcessedFile)) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    // ignore the event range options for all but the first processed task
    if (currentTask != fTasks.begin()) {
      fOptions.resetEventRange();
    }

    INFO(Form("Starting task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
    (*currentTask)->init(fOptions.getOptions());
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
  }
  return true;
}

void* JPetTaskExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskExecutor::run()
{
  TThread* thread = new TThread(to_string(fProcessedFile).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskExecutor::processFromCmdLineArgs(int)
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }
  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    createScopeTaskAndAddToTaskList();
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    if (nevents > 0) {
      fUnpacker.setParams(fOptions.getInputFile(), nevents);
      WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
    } else {
      fUnpacker.setParams(fOptions.getInputFile());
    }
    unpackFile();
  }
  return true;
}

void JPetTaskExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
  }
  fTasks.push_front(module);
}

void JPetTaskExecutor::unpackFile()
{
  if (fOptions.getInputFileType() == JPetOptions::kHld) {
    fUnpacker.exec();
  } else {
    WARNING("Input file is not hld and unpacker was supposed to be called!");
  }
}

JPetTaskExecutor::~JPetTaskExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<commit_msg>Add logic that for the tasks that are not first changes the output paths options correctly<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  @file JPetTaskExecutor.cpp
 */

#include "JPetTaskExecutor.h"
#include <cassert>
#include "../JPetTaskInterface/JPetTaskInterface.h"
#include "../JPetScopeLoader/JPetScopeLoader.h"
#include "../JPetTaskLoader/JPetTaskLoader.h"
#include "../JPetParamGetterAscii/JPetParamGetterAscii.h"
#include "../JPetParamGetterAscii/JPetParamSaverAscii.h"
#include "../JPetLoggerInclude.h"

JPetTaskExecutor::JPetTaskExecutor(TaskGeneratorChain* taskGeneratorChain, int processedFileId, JPetOptions opt) :
  fProcessedFile(processedFileId),
  ftaskGeneratorChain(taskGeneratorChain),
  fOptions(opt)
{
  if (fOptions.isLocalDB()) {
    fParamManager = new JPetParamManager(new JPetParamGetterAscii(fOptions.getLocalDB()));
  } else {
    fParamManager = new JPetParamManager();
  }
  if (taskGeneratorChain) {
    for (auto taskGenerator : *ftaskGeneratorChain) {
      auto task = taskGenerator();
      task->setParamManager(fParamManager); // maybe that should not be here
      fTasks.push_back(task);
    }
  } else {
    ERROR("taskGeneratorChain is null while constructing JPetTaskExecutor");
  }
}

bool JPetTaskExecutor::process()
{
  if(!processFromCmdLineArgs(fProcessedFile)) {
    ERROR("Error in processFromCmdLineArgs");
    return false;
  }
  for (auto currentTask = fTasks.begin(); currentTask != fTasks.end(); currentTask++) {
    JPetOptions::Options currOpts = fOptions.getOptions();
    if (currentTask != fTasks.begin()) {
    /// Ignore the event range options for all but the first task.
      currOpts = JPetOptions::resetEventRange(currOpts);
   /// For all but the first task,
   /// the input path must be changed if
   /// the output path argument -o was given, because the input
   /// data for them will lay in the location defined by -o.
      auto outPath  = currOpts.at("outputPath");
      if (!outPath.empty()) {
        currOpts.at("inputFile") = outPath + JPetCommonTools::extractPathFromFile(currOpts.at("inputFile")) + JPetCommonTools::extractFileNameFromFullPath(currOpts.at("inputFile"));
      }
    }

    INFO(Form("Starting task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
    (*currentTask)->init(currOpts);
    (*currentTask)->exec();
    (*currentTask)->terminate();
    INFO(Form("Finished task: %s", dynamic_cast<JPetTaskLoader*>(*currentTask)->getSubTask()->GetName()));
  }
  return true;
}

void* JPetTaskExecutor::processProxy(void* runner)
{
  assert(runner);
  static_cast<JPetTaskExecutor*>(runner)->process();
  return 0;
}

TThread* JPetTaskExecutor::run()
{
  TThread* thread = new TThread(to_string(fProcessedFile).c_str(), processProxy, (void*)this);
  assert(thread);
  thread->Run();
  return thread;
}

bool JPetTaskExecutor::processFromCmdLineArgs(int)
{
  auto runNum = fOptions.getRunNumber();
  if (runNum >= 0) {
    try {
      fParamManager->fillParameterBank(runNum);
    } catch (...) {
      ERROR("Param bank was not generated correctly.\n The run number used:" + JPetCommonTools::intToString(runNum));
      return false;
    }
    if (fOptions.isLocalDBCreate()) {
      JPetParamSaverAscii saver;
      saver.saveParamBank(fParamManager->getParamBank(), runNum, fOptions.getLocalDBCreate());
    }
  }
  auto inputFileType = fOptions.getInputFileType();
  auto inputFile = fOptions.getInputFile();
  if (inputFileType == JPetOptions::kScope) {
    createScopeTaskAndAddToTaskList();
  } else if (inputFileType == JPetOptions::kHld) {
    long long nevents = fOptions.getTotalEvents();
    if (nevents > 0) {
      fUnpacker.setParams(fOptions.getInputFile(), nevents);
      WARNING(std::string("Even though the range of events was set, only the first ") + JPetCommonTools::intToString(nevents) + std::string(" will be unpacked by the unpacker. \n The unpacker always starts from the beginning of the file."));
    } else {
      fUnpacker.setParams(fOptions.getInputFile());
    }
    unpackFile();
  }
  return true;
}

void JPetTaskExecutor::createScopeTaskAndAddToTaskList()
{
  JPetScopeLoader* module = new JPetScopeLoader(new JPetScopeTask("JPetScopeReader", "Process Oscilloscope ASCII data into JPetRecoSignal structures."));
  assert(module);
  module->setParamManager(fParamManager);
  auto scopeFile = fOptions.getScopeConfigFile();
  if (!fParamManager->getParametersFromScopeConfig(scopeFile)) {
    ERROR("Unable to generate Param Bank from Scope Config");
  }
  fTasks.push_front(module);
}

void JPetTaskExecutor::unpackFile()
{
  if (fOptions.getInputFileType() == JPetOptions::kHld) {
    fUnpacker.exec();
  } else {
    WARNING("Input file is not hld and unpacker was supposed to be called!");
  }
}

JPetTaskExecutor::~JPetTaskExecutor()
{
  for (auto & task : fTasks) {
    if (task) {
      delete task;
      task = 0;
    }
  }
}
<|endoftext|>


<commit_before>#include "projet.h"
#include <QtDebug>
#include <QProcess>
#include <QException>
#include <QPainter>

const QSize Projet::sizeOutput = QSize(1002, 561);

Projet::Projet()
{

}

QImage* Projet::getImageVideo(int number)
{
    return _imagesVideo.at(number);
}

QImage* Projet::getImageOutput(int number)
{
    return _imagesOutput.at(number);
}

int Projet::getNbFrameVideo()
{
    return _nbFrameVideo;
}

Projet* Projet::create(QString &name, QDir &workspace, QFile &video, int frequenceVideo)
{
    Projet *projet = new Projet();

    projet->_frequenceVideo = frequenceVideo;

    if(workspace.exists())
    {
        if(video.exists())
        {
            if(workspace.mkdir(name))
            {
                projet->_project = new QDir(workspace.path()+"/"+name);
                qDebug() << projet->_project->path();
                projet->_project->mkdir("input");
                projet->_input = new QDir(projet->_project->path()+"/input");
                projet->_project->mkdir("output");
                projet->_output = new QDir(projet->_project->path()+"/output");
                video.copy(projet->_project->path()+"/input/video");
                projet->_video = new QFile(projet->_project->path()+"/input/video");

                QProcess process;
                process.start("avconv -i " + projet->_project->path() +"/input/video -vsync 1 -s " + QString::number(sizeOutput.width()) + "x" + QString::number(projet->sizeOutput.height()) + " -r " +  QString::number(projet->_frequenceVideo) + " -y " + projet->_project->path() + "/input/img%d.bmp");
                process.waitForFinished(-1);

                QStringList filters;
                filters << "img*.bmp";
                projet->_nbFrameVideo = projet->_input->entryList(filters).count();
                qDebug() << "Nombre de frames : " << projet->_nbFrameVideo;

                QFile file(projet->_project->path() + "/info");
                file.open(QIODevice::WriteOnly | QIODevice::Text);
                QTextStream out(&file);

                out << QString::number(projet->_frequenceVideo) << "\n" << QString::number(projet->_nbFrameVideo);

                file.close();

                for(int i = 1; i <= projet->_nbFrameVideo; i++)
                {
                    projet->_imagesVideo.push_back(new QImage(projet->_input->path()+"/img"+QString::number(i)+".bmp"));
                    QImage *image = new QImage(projet->sizeOutput.width(),projet->sizeOutput.height(),QImage::Format_ARGB32);
                    image->save(projet->_output->path() + "/img" + QString::number(i) + ".png");
                    projet->_imagesOutput.push_back(image);
                }
            }
            else
            {
                throw QString("Ce projet existe déjà");
            }
        }
        else
        {
            throw QString("La vidéo n'existe pas");
        }
    }
    else
    {
        throw QString("Le workspace n'existe pas");
    }

    return projet;
}

Projet* Projet::open(QDir &path)
{
    Projet *projet = new Projet();

    if(path.exists())
    {
        projet->_project = new QDir(path.path());
        projet->_input = new QDir(path.path() + "/input");
        projet->_output = new QDir(path.path() + "/output");

        QFile info(projet->_project->path() + "/info");

        if(info.exists())
        {
            info.open(QIODevice::ReadOnly | QIODevice::Text);
            QTextStream in(&info);

            QString string;
            in >> string;
            projet->_frequenceVideo = string.toInt();

            in >> string;
            projet->_nbFrameVideo = string.toInt();

            qDebug() << "Frequence : " << projet->_frequenceVideo;
            qDebug() << "Nombre de frames : " << projet->_nbFrameVideo;
        }
        else
        {
            throw QString("Le projet n'est pas complet");
        }

        if(projet->_input->exists() && projet->_output->exists())
        {
            projet->_video = new QFile(projet->_input->path() + "/video");

            if(!projet->_video->exists())
            {
                throw QString("Le projet n'est pas complet");
            }

            for(int i = 1; i <= projet->_nbFrameVideo; i++)
            {
                try
                {
                    projet->_imagesVideo.push_back(new QImage(projet->_input->path() + "/img" + QString::number(i) + ".bmp"));
                    projet->_imagesOutput.push_back(new QImage(projet->_output->path() + "/img" + QString::number(i) + ".png"));
                }
                catch(QException e)
                {
                    throw QString("Le projet n'est pas complet");
                }
            }
        }
        else
        {
            throw QString("Ce projet est mal formé");
        }
    }
    else
    {
        throw QString("Ce projet n'existe pas");
    }

    return projet;
}

void Projet::save()
{
    for(size_t i = 0; i < _imagesOutput.size(); i++)
    {
        _imagesOutput.at(i)->save(_output->path()+"/img" + QString::number(i+1) + ".png");
    }
}

void Projet::saveAs(QDir &projet)
{
    if(projet.exists())
    {
        if(projet.count() == 2) //Les 2 correspond à . et ..
        {
            QProcess::execute("cp -r " + _project->absolutePath() + "/input " + projet.absolutePath() + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/output " + projet.absolutePath() + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/info " + projet.absolutePath() + "/");

            _project = projet;
            _input = QDir(projet.path() + "/input");
            _output = QDir(projet.path() + "/output");
            _video = QFile(projet.path() + "/input/video");

            save();
        }
        else
        {
            throw QString("Ce dossier n'est pas vide");
        }
    }
    else
    {
        QString name(projet.dirName());
        if(projet.cdUp() && projet.mkdir(name))
        {
            QProcess::execute("cp -r " + _project->absolutePath() + "/input " + projet.absolutePath() + "/" + name + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/output " + projet.absolutePath() + "/" + name + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/info " + projet.absolutePath() + "/" + name + "/");

            _project = projet + "/" + name;
            _input = QDir(_project.path() + "/input");
            _output = QDir(_project.path() + "/output");
            _video = QFile(_project.path() + "/input/video");

            save();
        }
        else
        {
            throw QString("Ce dossier n'existe pas");
        }
    }
}
<commit_msg>Corrections<commit_after>#include "projet.h"
#include <QtDebug>
#include <QProcess>
#include <QException>
#include <QPainter>

const QSize Projet::sizeOutput = QSize(1002, 561);

Projet::Projet()
{

}

QImage* Projet::getImageVideo(int number)
{
    return _imagesVideo.at(number);
}

QImage* Projet::getImageOutput(int number)
{
    return _imagesOutput.at(number);
}

int Projet::getNbFrameVideo()
{
    return _nbFrameVideo;
}

Projet* Projet::create(QString &name, QDir &workspace, QFile &video, int frequenceVideo)
{
    Projet *projet = new Projet();

    projet->_frequenceVideo = frequenceVideo;

    if(workspace.exists())
    {
        if(video.exists())
        {
            if(workspace.mkdir(name))
            {
                projet->_project = new QDir(workspace.path()+"/"+name);
                qDebug() << projet->_project->path();
                projet->_project->mkdir("input");
                projet->_input = new QDir(projet->_project->path()+"/input");
                projet->_project->mkdir("output");
                projet->_output = new QDir(projet->_project->path()+"/output");
                video.copy(projet->_project->path()+"/input/video");
                projet->_video = new QFile(projet->_project->path()+"/input/video");

                QProcess process;
                process.start("avconv -i " + projet->_project->path() +"/input/video -vsync 1 -s " + QString::number(sizeOutput.width()) + "x" + QString::number(projet->sizeOutput.height()) + " -r " +  QString::number(projet->_frequenceVideo) + " -y " + projet->_project->path() + "/input/img%d.bmp");
                process.waitForFinished(-1);

                QStringList filters;
                filters << "img*.bmp";
                projet->_nbFrameVideo = projet->_input->entryList(filters).count();
                qDebug() << "Nombre de frames : " << projet->_nbFrameVideo;

                QFile file(projet->_project->path() + "/info");
                file.open(QIODevice::WriteOnly | QIODevice::Text);
                QTextStream out(&file);

                out << QString::number(projet->_frequenceVideo) << "\n" << QString::number(projet->_nbFrameVideo);

                file.close();

                for(int i = 1; i <= projet->_nbFrameVideo; i++)
                {
                    projet->_imagesVideo.push_back(new QImage(projet->_input->path()+"/img"+QString::number(i)+".bmp"));
                    QImage *image = new QImage(projet->sizeOutput.width(),projet->sizeOutput.height(),QImage::Format_ARGB32);
                    image->save(projet->_output->path() + "/img" + QString::number(i) + ".png");
                    projet->_imagesOutput.push_back(image);
                }
            }
            else
            {
                throw QString("Ce projet existe déjà");
            }
        }
        else
        {
            throw QString("La vidéo n'existe pas");
        }
    }
    else
    {
        throw QString("Le workspace n'existe pas");
    }

    return projet;
}

Projet* Projet::open(QDir &path)
{
    Projet *projet = new Projet();

    if(path.exists())
    {
        projet->_project = new QDir(path.path());
        projet->_input = new QDir(path.path() + "/input");
        projet->_output = new QDir(path.path() + "/output");

        QFile info(projet->_project->path() + "/info");

        if(info.exists())
        {
            info.open(QIODevice::ReadOnly | QIODevice::Text);
            QTextStream in(&info);

            QString string;
            in >> string;
            projet->_frequenceVideo = string.toInt();

            in >> string;
            projet->_nbFrameVideo = string.toInt();

            qDebug() << "Frequence : " << projet->_frequenceVideo;
            qDebug() << "Nombre de frames : " << projet->_nbFrameVideo;
        }
        else
        {
            throw QString("Le projet n'est pas complet");
        }

        if(projet->_input->exists() && projet->_output->exists())
        {
            projet->_video = new QFile(projet->_input->path() + "/video");

            if(!projet->_video->exists())
            {
                throw QString("Le projet n'est pas complet");
            }

            for(int i = 1; i <= projet->_nbFrameVideo; i++)
            {
                try
                {
                    projet->_imagesVideo.push_back(new QImage(projet->_input->path() + "/img" + QString::number(i) + ".bmp"));
                    projet->_imagesOutput.push_back(new QImage(projet->_output->path() + "/img" + QString::number(i) + ".png"));
                }
                catch(QException e)
                {
                    throw QString("Le projet n'est pas complet");
                }
            }
        }
        else
        {
            throw QString("Ce projet est mal formé");
        }
    }
    else
    {
        throw QString("Ce projet n'existe pas");
    }

    return projet;
}

void Projet::save()
{
    for(size_t i = 0; i < _imagesOutput.size(); i++)
    {
        _imagesOutput.at(i)->save(_output->path()+"/img" + QString::number(i+1) + ".png");
    }
}

void Projet::saveAs(QDir &projet)
{
    if(projet.exists())
    {
        if(projet.count() == 2) //Les 2 correspond à . et ..
        {
            QProcess::execute("cp -r " + _project->absolutePath() + "/input " + projet.absolutePath() + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/output " + projet.absolutePath() + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/info " + projet.absolutePath() + "/");

            _project = new QDir(projet);
            _input = new QDir(projet.path() + "/input");
            _output = new QDir(projet.path() + "/output");
            _video = new QFile(projet.path() + "/input/video");

            save();
        }
        else
        {
            throw QString("Ce dossier n'est pas vide");
        }
    }
    else
    {
        QString name(projet.dirName());
        if(projet.cdUp() && projet.mkdir(name))
        {
            QProcess::execute("cp -r " + _project->absolutePath() + "/input " + projet.absolutePath() + "/" + name + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/output " + projet.absolutePath() + "/" + name + "/");
            QProcess::execute("cp -r " + _project->absolutePath() + "/info " + projet.absolutePath() + "/" + name + "/");

            _project = new QDir(projet.path() + "/" + name);
            _input = new QDir(_project->path() + "/input");
            _output = new QDir(_project->path() + "/output");
            _video = new QFile(_project->path() + "/input/video");

            save();
        }
        else
        {
            throw QString("Ce dossier n'existe pas");
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "tools/fiddle/examples.h"
REG_FIDDLE(GradientShader_MakeLinear, 201, 201, false, 0) {
void draw(SkCanvas* canvas) {
    // This fiddle draws 4 instances of a LinearGradient, demonstrating
    // how the local matrix affects the gradient as well as the flag
    // which controls unpremul vs premul color interpolation.

    SkPaint strokePaint;
    strokePaint.setStyle(SkPaint::kStroke_Style);
    strokePaint.setColor(SK_ColorBLACK);

    SkPaint p;
    p.setStyle(SkPaint::kFill_Style);

    SkColor transparentGreen = SkColorSetARGB(0, 0, 255, 255);
    SkColor colors[] = { transparentGreen, SK_ColorBLUE, SK_ColorRED };
    SkScalar positions[] = { 0.0, 0.65, 1.0 };

    for (int i = 0; i < 4; i++) {
        SkScalar blockX = (i / 2) * 100;
        SkScalar blockY = (i % 2) * 100;
        SkPoint pts[] = { {blockX, blockY}, {blockX + 50, blockY + 100} };

        int flags = 0; // interpolate colors in unpremul
        if (i % 2 == 1) {
            // right column will have premul
            flags = SkGradientShader::Flags::kInterpolateColorsInPremul_Flag;
        }

        SkMatrix* matr = nullptr;
        if (i / 2 == 1) {
            // bottom row will be rotated 45 degrees.
            SkMatrix m;
            m.setRotate(45, blockX, blockY);
            matr = &m;
        }

        auto lgs = SkGradientShader::MakeLinear(
        pts, colors, positions, 3, SkTileMode::kMirror,
        flags, matr);

        p.setShader(lgs);
        auto r = SkRect::MakeLTRB(blockX, blockY, blockX + 100, blockY + 100);
        canvas->drawRect(r, p);
        canvas->drawRect(r, strokePaint);
    }
}
}  // END FIDDLE
<commit_msg>Fix matrix scoping issue in sample<commit_after>// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "tools/fiddle/examples.h"
REG_FIDDLE(GradientShader_MakeLinear, 201, 201, false, 0) {
void draw(SkCanvas* canvas) {
    // This fiddle draws 4 instances of a LinearGradient, demonstrating
    // how the local matrix affects the gradient as well as the flag
    // which controls unpremul vs premul color interpolation.

    SkPaint strokePaint;
    strokePaint.setStyle(SkPaint::kStroke_Style);
    strokePaint.setColor(SK_ColorBLACK);

    SkPaint p;
    p.setStyle(SkPaint::kFill_Style);

    SkColor transparentGreen = SkColorSetARGB(0, 0, 255, 255);
    SkColor colors[] = { transparentGreen, SK_ColorBLUE, SK_ColorRED };
    SkScalar positions[] = { 0.0, 0.65, 1.0 };

    for (int i = 0; i < 4; i++) {
        SkScalar blockX = (i % 2) * 100;
        SkScalar blockY = (i / 2) * 100;
        SkPoint pts[] = { {blockX, blockY}, {blockX + 50, blockY + 100} };

        int flags = 0; // interpolate colors in unpremul
        if (i % 2 == 1) {
            // right column will have premul
            flags = SkGradientShader::Flags::kInterpolateColorsInPremul_Flag;
        }

        SkMatrix matr = SkMatrix::I();
        if (i / 2 == 1) {
            // bottom row will be rotated 45 degrees.
            matr.setRotate(45, blockX, blockY);
        }

        auto lgs = SkGradientShader::MakeLinear(
            pts, colors, positions, 3, SkTileMode::kMirror,
            flags, &matr);

        p.setShader(lgs);
        auto r = SkRect::MakeLTRB(blockX, blockY, blockX + 100, blockY + 100);
        canvas->drawRect(r, p);
        canvas->drawRect(r, strokePaint);
    }
}
}  // END FIDDLE
<|endoftext|>


<commit_before>
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <unistd.h>

#include <list>
#include <map>
#include <sstream>

// This is an example of using ptrace() to log syscalls called by a
// child process.

namespace {

// Flag which is set in the signal number for syscall entry/exit when
// the option PTRACE_O_TRACESYSGOOD is enabled.
const int kSysFlag = 0x80;

const char *SyscallName(int sysnum) {
  switch (sysnum) {
#define MAP(name) case __NR_##name: return #name;
    MAP(access)
    MAP(arch_prctl)
    MAP(brk)
    MAP(close)
    MAP(execve)
    MAP(exit)
    MAP(exit_group)
    MAP(fstat)
    MAP(mmap)
    MAP(mprotect)
    MAP(munmap)
    MAP(open)
    MAP(read)
    MAP(write)
    default: return "?";
  }
}

uintptr_t RoundUpPageSize(uintptr_t val) {
  uintptr_t page_size = getpagesize();
  return (val + page_size - 1) & ~(page_size - 1);
}

class MmapInfo {
 public:
  uintptr_t addr;
  size_t size;
  int prot;
  std::string filename;
  uint64_t file_offset;
};

class Ptracer {
  int pid_;
  std::list<MmapInfo> mappings_;
  std::map<int, std::string> fds_;
  FILE *info_fp_;

  uintptr_t ReadWord(uintptr_t addr) {
    errno = 0;
    uintptr_t value = ptrace(PTRACE_PEEKDATA, pid_, addr, 0);
    assert(errno == 0);
    return value;
  }

  char ReadByte(uintptr_t addr) {
    uintptr_t mask = sizeof(uintptr_t) - 1;
    uintptr_t word = ReadWord(addr & ~mask);
    return word >> ((addr & mask) * 8);
  }

  std::string ReadString(uintptr_t addr) {
    // TODO: Reading one byte at a time is inefficient (though reading
    // one word at a time is not great either).
    std::stringbuf buf;
    for (;;) {
      char ch = ReadByte(addr++);
      if (!ch)
        break;
      buf.sputc(ch);
    }
    return buf.str();
  }

 public:
  Ptracer(int pid): pid_(pid) {}

  void HandleSyscall(struct user_regs_struct *regs) {
    uintptr_t sysnum = regs->orig_rax;
    uintptr_t syscall_result = regs->rax;
    uintptr_t arg1 = regs->rdi;
    uintptr_t arg2 = regs->rsi;
    uintptr_t arg3 = regs->rdx;
    // uintptr_t arg4 = regs->r10;
    uintptr_t arg5 = regs->r8;
    uintptr_t arg6 = regs->r9;
    printf("syscall=%s (%i)\n", SyscallName(sysnum), (int) sysnum);

    if (syscall_result > -(uintptr_t) 0x1000) {
      // Syscall returned an error so should have had no effect.
      return;
    }

    switch (sysnum) {
      case __NR_open: {
        std::string filename(ReadString(arg1));
        printf("open: %s\n", filename.c_str());
        int fd_result = syscall_result;
        if (fd_result >= 0)
          fds_[fd_result] = filename;
        break;
      }
      case __NR_mmap: {
        MmapInfo map;
        map.addr = syscall_result;
        map.size = RoundUpPageSize(arg2);
        map.prot = arg3;
        // assert(arg4 == (MAP_ANON | MAP_PRIVATE));
        int fd_arg = arg5;
        if (fd_arg != -1) {
          assert(fds_.find(fd_arg) != fds_.end());
          map.filename = fds_[fd_arg];
        }
        map.file_offset = arg6;
        mappings_.push_back(map);
        break;
      }
    }
  }

  void Put(uint64_t val) {
    fwrite(&val, sizeof(val), 1, info_fp_);
  }

  void PutString(const std::string &str) {
    Put(str.size());
    fwrite(str.c_str(), str.size() + 1, 1, info_fp_);
  }

  void Dump() {
    FILE *mapfile = fopen("out_pages", "w");
    assert(mapfile);
    uintptr_t mapfile_offset = 0;

    info_fp_ = fopen("out_info", "w");
    assert(info_fp_);

    struct user_regs_struct regs;
    int rc = ptrace(PTRACE_GETREGS, pid_, 0, &regs);
    assert(rc == 0);
    Put(regs.rip);

    Put(mappings_.size());
    for (auto map : mappings_) {
      Put(map.addr);
      Put(map.size);
      Put(map.prot);
      PutString(map.filename);
      Put(map.file_offset);

      if (map.prot & PROT_WRITE) {
        Put(mapfile_offset);
        for (uintptr_t offset = 0; offset < map.size;
             offset += sizeof(uintptr_t)) {
          uintptr_t word = ReadWord(map.addr + offset);
          fwrite(&word, sizeof(word), 1, mapfile);
        }
        mapfile_offset += map.size;
      }
    }
    fclose(mapfile);
    fclose(info_fp_);
  }

  void TerminateSubprocess() {
    int rc = kill(pid_, SIGKILL);
    assert(rc == 0);

    // Wait for the SIGKILL signal to take effect.
    int status;
    int pid2 = waitpid(pid_, &status, 0);
    assert(pid2 == pid_);
    assert(WIFSIGNALED(status));
    assert(WTERMSIG(status) == SIGKILL);
  }
};

}

int main(int argc, char **argv) {
  assert(argc >= 2);

  int pid = fork();
  assert(pid >= 0);
  if (pid == 0) {
    // Start tracing of the current process by the parent process.
    int rc = ptrace(PTRACE_TRACEME);
    assert(rc == 0);

    // This will trigger a SIGTRAP signal, which the parent will catch.
    execv(argv[1], argv + 1);
    perror("exec");

    _exit(1);
  }

  // Wait for the initial SIGTRAP signal generated by the child's
  // execve() call.  Since we haven't done PTRACE_SETOPTIONS yet,
  // kSysFlag isn't set in the signal number yet.
  int status;
  int pid2 = waitpid(pid, &status, 0);
  assert(pid2 == pid);
  assert(WIFSTOPPED(status));
  assert(WSTOPSIG(status) == SIGTRAP);

  // Enable kSysFlag.
  int rc = ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD);
  assert(rc == 0);

  // Allow the process to continue until the next syscall entry/exit.
  rc = ptrace(PTRACE_SYSCALL, pid, 0, 0);
  assert(rc == 0);

  // Whether the next signal will indicate a syscall entry.  If false,
  // the next signal will indicate a syscall exit.
  bool syscall_entry = true;

  Ptracer ptracer(pid);
  for (;;) {
    int status;
    int rc = waitpid(pid, &status, 0);
    assert(rc == pid);

    assert(WIFSTOPPED(status));

    if (WSTOPSIG(status) == (SIGTRAP | kSysFlag)) {
      if (!syscall_entry) {
        struct user_regs_struct regs;
        rc = ptrace(PTRACE_GETREGS, pid, 0, &regs);
        assert(rc == 0);
        ptracer.HandleSyscall(&regs);
      }
      syscall_entry = !syscall_entry;

      // Allow the process to continue until the next syscall entry/exit.
      rc = ptrace(PTRACE_SYSCALL, pid, 0, 0);
      assert(rc == 0);
    } else if (WSTOPSIG(status) == SIGUSR1) {
      ptracer.Dump();
      ptracer.TerminateSubprocess();
      break;
    }
  }
  return 0;
}
<commit_msg>Implement close() and check that no FDs have been left open<commit_after>
#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <unistd.h>

#include <list>
#include <map>
#include <sstream>

// This is an example of using ptrace() to log syscalls called by a
// child process.

namespace {

// Flag which is set in the signal number for syscall entry/exit when
// the option PTRACE_O_TRACESYSGOOD is enabled.
const int kSysFlag = 0x80;

const char *SyscallName(int sysnum) {
  switch (sysnum) {
#define MAP(name) case __NR_##name: return #name;
    MAP(access)
    MAP(arch_prctl)
    MAP(brk)
    MAP(close)
    MAP(execve)
    MAP(exit)
    MAP(exit_group)
    MAP(fstat)
    MAP(mmap)
    MAP(mprotect)
    MAP(munmap)
    MAP(open)
    MAP(read)
    MAP(write)
    default: return "?";
  }
}

uintptr_t RoundUpPageSize(uintptr_t val) {
  uintptr_t page_size = getpagesize();
  return (val + page_size - 1) & ~(page_size - 1);
}

class MmapInfo {
 public:
  uintptr_t addr;
  size_t size;
  int prot;
  std::string filename;
  uint64_t file_offset;
};

class Ptracer {
  int pid_;
  std::list<MmapInfo> mappings_;
  std::map<int, std::string> fds_;
  FILE *info_fp_;

  uintptr_t ReadWord(uintptr_t addr) {
    errno = 0;
    uintptr_t value = ptrace(PTRACE_PEEKDATA, pid_, addr, 0);
    assert(errno == 0);
    return value;
  }

  char ReadByte(uintptr_t addr) {
    uintptr_t mask = sizeof(uintptr_t) - 1;
    uintptr_t word = ReadWord(addr & ~mask);
    return word >> ((addr & mask) * 8);
  }

  std::string ReadString(uintptr_t addr) {
    // TODO: Reading one byte at a time is inefficient (though reading
    // one word at a time is not great either).
    std::stringbuf buf;
    for (;;) {
      char ch = ReadByte(addr++);
      if (!ch)
        break;
      buf.sputc(ch);
    }
    return buf.str();
  }

 public:
  Ptracer(int pid): pid_(pid) {}

  void HandleSyscall(struct user_regs_struct *regs) {
    uintptr_t sysnum = regs->orig_rax;
    uintptr_t syscall_result = regs->rax;
    uintptr_t arg1 = regs->rdi;
    uintptr_t arg2 = regs->rsi;
    uintptr_t arg3 = regs->rdx;
    // uintptr_t arg4 = regs->r10;
    uintptr_t arg5 = regs->r8;
    uintptr_t arg6 = regs->r9;
    printf("syscall=%s (%i)\n", SyscallName(sysnum), (int) sysnum);

    if (syscall_result > -(uintptr_t) 0x1000) {
      // Syscall returned an error so should have had no effect.
      return;
    }

    switch (sysnum) {
      case __NR_open: {
        std::string filename(ReadString(arg1));
        printf("open: %s\n", filename.c_str());
        int fd_result = syscall_result;
        if (fd_result >= 0)
          fds_[fd_result] = filename;
        break;
      }
      case __NR_close: {
        fds_.erase(arg1);
        break;
      }
      case __NR_mmap: {
        MmapInfo map;
        map.addr = syscall_result;
        map.size = RoundUpPageSize(arg2);
        map.prot = arg3;
        // assert(arg4 == (MAP_ANON | MAP_PRIVATE));
        int fd_arg = arg5;
        if (fd_arg != -1) {
          assert(fds_.find(fd_arg) != fds_.end());
          map.filename = fds_[fd_arg];
        }
        map.file_offset = arg6;
        mappings_.push_back(map);
        break;
      }
    }
  }

  void Put(uint64_t val) {
    fwrite(&val, sizeof(val), 1, info_fp_);
  }

  void PutString(const std::string &str) {
    Put(str.size());
    fwrite(str.c_str(), str.size() + 1, 1, info_fp_);
  }

  void Dump() {
    // We don't support restoring FDs yet, so no FDs must be left open.
    assert(fds_.size() == 0);

    FILE *mapfile = fopen("out_pages", "w");
    assert(mapfile);
    uintptr_t mapfile_offset = 0;

    info_fp_ = fopen("out_info", "w");
    assert(info_fp_);

    struct user_regs_struct regs;
    int rc = ptrace(PTRACE_GETREGS, pid_, 0, &regs);
    assert(rc == 0);
    Put(regs.rip);

    Put(mappings_.size());
    for (auto map : mappings_) {
      Put(map.addr);
      Put(map.size);
      Put(map.prot);
      PutString(map.filename);
      Put(map.file_offset);

      if (map.prot & PROT_WRITE) {
        Put(mapfile_offset);
        for (uintptr_t offset = 0; offset < map.size;
             offset += sizeof(uintptr_t)) {
          uintptr_t word = ReadWord(map.addr + offset);
          fwrite(&word, sizeof(word), 1, mapfile);
        }
        mapfile_offset += map.size;
      }
    }
    fclose(mapfile);
    fclose(info_fp_);
  }

  void TerminateSubprocess() {
    int rc = kill(pid_, SIGKILL);
    assert(rc == 0);

    // Wait for the SIGKILL signal to take effect.
    int status;
    int pid2 = waitpid(pid_, &status, 0);
    assert(pid2 == pid_);
    assert(WIFSIGNALED(status));
    assert(WTERMSIG(status) == SIGKILL);
  }
};

}

int main(int argc, char **argv) {
  assert(argc >= 2);

  int pid = fork();
  assert(pid >= 0);
  if (pid == 0) {
    // Start tracing of the current process by the parent process.
    int rc = ptrace(PTRACE_TRACEME);
    assert(rc == 0);

    // This will trigger a SIGTRAP signal, which the parent will catch.
    execv(argv[1], argv + 1);
    perror("exec");

    _exit(1);
  }

  // Wait for the initial SIGTRAP signal generated by the child's
  // execve() call.  Since we haven't done PTRACE_SETOPTIONS yet,
  // kSysFlag isn't set in the signal number yet.
  int status;
  int pid2 = waitpid(pid, &status, 0);
  assert(pid2 == pid);
  assert(WIFSTOPPED(status));
  assert(WSTOPSIG(status) == SIGTRAP);

  // Enable kSysFlag.
  int rc = ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD);
  assert(rc == 0);

  // Allow the process to continue until the next syscall entry/exit.
  rc = ptrace(PTRACE_SYSCALL, pid, 0, 0);
  assert(rc == 0);

  // Whether the next signal will indicate a syscall entry.  If false,
  // the next signal will indicate a syscall exit.
  bool syscall_entry = true;

  Ptracer ptracer(pid);
  for (;;) {
    int status;
    int rc = waitpid(pid, &status, 0);
    assert(rc == pid);

    assert(WIFSTOPPED(status));

    if (WSTOPSIG(status) == (SIGTRAP | kSysFlag)) {
      if (!syscall_entry) {
        struct user_regs_struct regs;
        rc = ptrace(PTRACE_GETREGS, pid, 0, &regs);
        assert(rc == 0);
        ptracer.HandleSyscall(&regs);
      }
      syscall_entry = !syscall_entry;

      // Allow the process to continue until the next syscall entry/exit.
      rc = ptrace(PTRACE_SYSCALL, pid, 0, 0);
      assert(rc == 0);
    } else if (WSTOPSIG(status) == SIGUSR1) {
      ptracer.Dump();
      ptracer.TerminateSubprocess();
      break;
    }
  }
  return 0;
}
<|endoftext|>