<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

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

*/

#ifndef TORRENT_SESSION_SETTINGS_HPP_INCLUDED
#define TORRENT_SESSION_SETTINGS_HPP_INCLUDED

#include "libtorrent/version.hpp"
#include "libtorrent/config.hpp"

namespace libtorrent
{

	struct TORRENT_EXPORT proxy_settings
	{
		proxy_settings() : port(0), type(none) {}

		std::string hostname;
		int port;

		std::string username;
		std::string password;

		enum proxy_type
		{
			// a plain tcp socket is used, and
			// the other settings are ignored.
			none,
			// socks4 server, requires username.
			socks4,
			// the hostname and port settings are
			// used to connect to the proxy. No
			// username or password is sent.
			socks5,
			// the hostname and port are used to
			// connect to the proxy. the username
			// and password are used to authenticate
			// with the proxy server.
			socks5_pw,
			// the http proxy is only available for
			// tracker and web seed traffic
			// assumes anonymous access to proxy
			http,
			// http proxy with basic authentication
			// uses username and password
			http_pw
		};

		proxy_type type;

	};

	struct TORRENT_EXPORT session_settings
	{
		session_settings(std::string const& user_agent_ = "libtorrent/"
			LIBTORRENT_VERSION)
			: user_agent(user_agent_)
			, tracker_completion_timeout(60)
			, tracker_receive_timeout(20)
			, stop_tracker_timeout(5)
			, tracker_maximum_response_length(1024*1024)
			, piece_timeout(10)
			, request_queue_time(3.f)
			, max_allowed_in_request_queue(250)
			, max_out_request_queue(200)
			, whole_pieces_threshold(20)
			, peer_timeout(120)
			, urlseed_timeout(20)
			, urlseed_pipeline_size(5)
			, urlseed_wait_retry(30)
			, file_pool_size(40)
			, allow_multiple_connections_per_ip(false)
			, max_failcount(3)
			, min_reconnect_time(60)
			, peer_connect_timeout(7)
			, ignore_limits_on_local_network(true)
			, connection_speed(20)
			, send_redundant_have(false)
			, lazy_bitfields(true)
			, inactivity_timeout(600)
			, unchoke_interval(15)
			, optimistic_unchoke_multiplier(4)
			, num_want(200)
			, initial_picker_threshold(4)
			, allowed_fast_set_size(10)
			, max_outstanding_disk_bytes_per_connection(64 * 1024)
			, handshake_timeout(10)
#ifndef TORRENT_DISABLE_DHT
			, use_dht_as_fallback(true)
#endif
			, free_torrent_hashes(true)
		{}

		// this is the user agent that will be sent to the tracker
		// when doing requests. It is used to identify the client.
		// It cannot contain \r or \n
		std::string user_agent;

		// the number of seconds to wait until giving up on a
		// tracker request if it hasn't finished
		int tracker_completion_timeout;

		// the number of seconds where no data is received
		// from the tracker until it should be considered
		// as timed out
		int tracker_receive_timeout;

		// the time to wait when sending a stopped message
		// before considering a tracker to have timed out.
		// this is usually shorter, to make the client quit
		// faster
		int stop_tracker_timeout;

		// if the content-length is greater than this value
		// the tracker connection will be aborted
		int tracker_maximum_response_length;

		// the number of seconds from a request is sent until
		// it times out if no piece response is returned.
		int piece_timeout;

		// the length of the request queue given in the number
		// of seconds it should take for the other end to send
		// all the pieces. i.e. the actual number of requests
		// depends on the download rate and this number.
		float request_queue_time;

		// the number of outstanding block requests a peer is
		// allowed to queue up in the client. If a peer sends
		// more requests than this (before the first one has
		// been sent) the last request will be dropped.
		// the higher this is, the faster upload speeds the
		// client can get to a single peer.
		int max_allowed_in_request_queue;

		// the maximum number of outstanding requests to
		// send to a peer. This limit takes precedence over
		// request_queue_time.
		int max_out_request_queue;

		// if a whole piece can be downloaded in this number
		// of seconds, or less, the peer_connection will prefer
		// to request whole pieces at a time from this peer.
		// The benefit of this is to better utilize disk caches by
		// doing localized accesses and also to make it easier
		// to identify bad peers if a piece fails the hash check.
		int whole_pieces_threshold;

		// the number of seconds to wait for any activity on
		// the peer wire before closing the connectiong due
		// to time out.
		int peer_timeout;

		// same as peer_timeout, but only applies to url-seeds.
		// this is usually set lower, because web servers are
		// expected to be more reliable.
		int urlseed_timeout;

		// controls the pipelining size of url-seeds
		int urlseed_pipeline_size;

		// time to wait until a new retry takes place
		int urlseed_wait_retry;

		// sets the upper limit on the total number of files this
		// session will keep open. The reason why files are
		// left open at all is that some anti virus software
		// hooks on every file close, and scans the file for
		// viruses. deferring the closing of the files will
		// be the difference between a usable system and
		// a completely hogged down system. Most operating
		// systems also has a limit on the total number of
		// file descriptors a process may have open. It is
		// usually a good idea to find this limit and set the
		// number of connections and the number of files
		// limits so their sum is slightly below it.
		int file_pool_size;

		// false to not allow multiple connections from the same
		// IP address. true will allow it.
		bool allow_multiple_connections_per_ip;

		// the number of times we can fail to connect to a peer
		// before we stop retrying it.
		int max_failcount;

		// the number of seconds to wait to reconnect to a peer.
		// this time is multiplied with the failcount.
		int min_reconnect_time;

		// this is the timeout for a connection attempt. If
		// the connect does not succeed within this time, the
		// connection is dropped. The time is specified in seconds.
		int peer_connect_timeout;

		// if set to true, upload, download and unchoke limits
		// are ignored for peers on the local network.
		bool ignore_limits_on_local_network;

		// the number of connection attempts that
		// are made per second.
		int connection_speed;

		// if this is set to true, have messages will be sent
		// to peers that already have the piece. This is
		// typically not necessary, but it might be necessary
		// for collecting statistics in some cases. Default is false.
		bool send_redundant_have;

		// if this is true, outgoing bitfields will never be fuil. If the
		// client is seed, a few bits will be set to 0, and later filled
		// in with have messages. This is to prevent certain ISPs
		// from stopping people from seeding.
		bool lazy_bitfields;

		// if a peer is uninteresting and uninterested for longer
		// than this number of seconds, it will be disconnected.
		// default is 10 minutes
		int inactivity_timeout;

		// the number of seconds between chokes/unchokes
		int unchoke_interval;

		// the number of unchoke intervals between
		// optimistic unchokes
		int optimistic_unchoke_multiplier;

		// if this is set, this IP will be reported do the
		// tracker in the ip= parameter.
		address announce_ip;

		// the num want sent to trackers
		int num_want;

		// while we have fewer pieces than this, pick
		// random pieces instead of rarest first.
		int initial_picker_threshold;

		// the number of allowed pieces to send to peers
		// that supports the fast extensions
		int allowed_fast_set_size;

		// the maximum number of bytes a connection may have
		// pending in the disk write queue before its download
		// rate is being throttled. This prevents fast downloads
		// to slow medias to allocate more and more memory
		// indefinitely. This should be set to at least 32 kB
		// to not completely disrupt normal downloads.
		int max_outstanding_disk_bytes_per_connection;

		// the number of seconds to wait for a handshake
		// response from a peer. If no response is received
		// within this time, the peer is disconnected.
		int handshake_timeout;

#ifndef TORRENT_DISABLE_DHT
		// while this is true, the dht will note be used unless the
		// tracker is online
		bool use_dht_as_fallback;
#endif

		// if this is true, the piece hashes will be freed, in order
		// to save memory, once the torrent is seeding. This will
		// make the get_torrent_info() function to return an incomplete
		// torrent object that cannot be passed back to add_torrent()
		bool free_torrent_hashes;
	};

#ifndef TORRENT_DISABLE_DHT
	struct dht_settings
	{
		dht_settings()
			: max_peers_reply(50)
			, search_branching(5)
			, service_port(0)
			, max_fail_count(20)
		{}

		// the maximum number of peers to send in a
		// reply to get_peers
		int max_peers_reply;

		// the number of simultanous "connections" when
		// searching the DHT.
		int search_branching;

		// the listen port for the dht. This is a UDP port.
		// zero means use the same as the tcp interface
		int service_port;

		// the maximum number of times a node can fail
		// in a row before it is removed from the table.
		int max_fail_count;
	};
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION

	struct pe_settings
	{
		pe_settings()
			: out_enc_policy(enabled)
			, in_enc_policy(enabled)
			, allowed_enc_level(both)
			, prefer_rc4(false)
		{}

		enum enc_policy
		{
			forced,  // disallow non encrypted connections
			enabled, // allow encrypted and non encrypted connections
			disabled // disallow encrypted connections
		};

		enum enc_level
		{
			plaintext, // use only plaintext encryption
			rc4, // use only rc4 encryption
			both // allow both
		};

		enc_policy out_enc_policy;
		enc_policy in_enc_policy;

		enc_level allowed_enc_level;
		// if the allowed encryption level is both, setting this to
		// true will prefer rc4 if both methods are offered, plaintext
		// otherwise
		bool prefer_rc4;
	};
#endif

}

#endif
<commit_msg>increased default tracker timeout from 20 seconds to 40 seconds<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

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

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

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

*/

#ifndef TORRENT_SESSION_SETTINGS_HPP_INCLUDED
#define TORRENT_SESSION_SETTINGS_HPP_INCLUDED

#include "libtorrent/version.hpp"
#include "libtorrent/config.hpp"

namespace libtorrent
{

	struct TORRENT_EXPORT proxy_settings
	{
		proxy_settings() : port(0), type(none) {}

		std::string hostname;
		int port;

		std::string username;
		std::string password;

		enum proxy_type
		{
			// a plain tcp socket is used, and
			// the other settings are ignored.
			none,
			// socks4 server, requires username.
			socks4,
			// the hostname and port settings are
			// used to connect to the proxy. No
			// username or password is sent.
			socks5,
			// the hostname and port are used to
			// connect to the proxy. the username
			// and password are used to authenticate
			// with the proxy server.
			socks5_pw,
			// the http proxy is only available for
			// tracker and web seed traffic
			// assumes anonymous access to proxy
			http,
			// http proxy with basic authentication
			// uses username and password
			http_pw
		};

		proxy_type type;

	};

	struct TORRENT_EXPORT session_settings
	{
		session_settings(std::string const& user_agent_ = "libtorrent/"
			LIBTORRENT_VERSION)
			: user_agent(user_agent_)
			, tracker_completion_timeout(60)
			, tracker_receive_timeout(40)
			, stop_tracker_timeout(5)
			, tracker_maximum_response_length(1024*1024)
			, piece_timeout(10)
			, request_queue_time(3.f)
			, max_allowed_in_request_queue(250)
			, max_out_request_queue(200)
			, whole_pieces_threshold(20)
			, peer_timeout(120)
			, urlseed_timeout(20)
			, urlseed_pipeline_size(5)
			, urlseed_wait_retry(30)
			, file_pool_size(40)
			, allow_multiple_connections_per_ip(false)
			, max_failcount(3)
			, min_reconnect_time(60)
			, peer_connect_timeout(7)
			, ignore_limits_on_local_network(true)
			, connection_speed(20)
			, send_redundant_have(false)
			, lazy_bitfields(true)
			, inactivity_timeout(600)
			, unchoke_interval(15)
			, optimistic_unchoke_multiplier(4)
			, num_want(200)
			, initial_picker_threshold(4)
			, allowed_fast_set_size(10)
			, max_outstanding_disk_bytes_per_connection(64 * 1024)
			, handshake_timeout(10)
#ifndef TORRENT_DISABLE_DHT
			, use_dht_as_fallback(true)
#endif
			, free_torrent_hashes(true)
		{}

		// this is the user agent that will be sent to the tracker
		// when doing requests. It is used to identify the client.
		// It cannot contain \r or \n
		std::string user_agent;

		// the number of seconds to wait until giving up on a
		// tracker request if it hasn't finished
		int tracker_completion_timeout;

		// the number of seconds where no data is received
		// from the tracker until it should be considered
		// as timed out
		int tracker_receive_timeout;

		// the time to wait when sending a stopped message
		// before considering a tracker to have timed out.
		// this is usually shorter, to make the client quit
		// faster
		int stop_tracker_timeout;

		// if the content-length is greater than this value
		// the tracker connection will be aborted
		int tracker_maximum_response_length;

		// the number of seconds from a request is sent until
		// it times out if no piece response is returned.
		int piece_timeout;

		// the length of the request queue given in the number
		// of seconds it should take for the other end to send
		// all the pieces. i.e. the actual number of requests
		// depends on the download rate and this number.
		float request_queue_time;

		// the number of outstanding block requests a peer is
		// allowed to queue up in the client. If a peer sends
		// more requests than this (before the first one has
		// been sent) the last request will be dropped.
		// the higher this is, the faster upload speeds the
		// client can get to a single peer.
		int max_allowed_in_request_queue;

		// the maximum number of outstanding requests to
		// send to a peer. This limit takes precedence over
		// request_queue_time.
		int max_out_request_queue;

		// if a whole piece can be downloaded in this number
		// of seconds, or less, the peer_connection will prefer
		// to request whole pieces at a time from this peer.
		// The benefit of this is to better utilize disk caches by
		// doing localized accesses and also to make it easier
		// to identify bad peers if a piece fails the hash check.
		int whole_pieces_threshold;

		// the number of seconds to wait for any activity on
		// the peer wire before closing the connectiong due
		// to time out.
		int peer_timeout;

		// same as peer_timeout, but only applies to url-seeds.
		// this is usually set lower, because web servers are
		// expected to be more reliable.
		int urlseed_timeout;

		// controls the pipelining size of url-seeds
		int urlseed_pipeline_size;

		// time to wait until a new retry takes place
		int urlseed_wait_retry;

		// sets the upper limit on the total number of files this
		// session will keep open. The reason why files are
		// left open at all is that some anti virus software
		// hooks on every file close, and scans the file for
		// viruses. deferring the closing of the files will
		// be the difference between a usable system and
		// a completely hogged down system. Most operating
		// systems also has a limit on the total number of
		// file descriptors a process may have open. It is
		// usually a good idea to find this limit and set the
		// number of connections and the number of files
		// limits so their sum is slightly below it.
		int file_pool_size;

		// false to not allow multiple connections from the same
		// IP address. true will allow it.
		bool allow_multiple_connections_per_ip;

		// the number of times we can fail to connect to a peer
		// before we stop retrying it.
		int max_failcount;

		// the number of seconds to wait to reconnect to a peer.
		// this time is multiplied with the failcount.
		int min_reconnect_time;

		// this is the timeout for a connection attempt. If
		// the connect does not succeed within this time, the
		// connection is dropped. The time is specified in seconds.
		int peer_connect_timeout;

		// if set to true, upload, download and unchoke limits
		// are ignored for peers on the local network.
		bool ignore_limits_on_local_network;

		// the number of connection attempts that
		// are made per second.
		int connection_speed;

		// if this is set to true, have messages will be sent
		// to peers that already have the piece. This is
		// typically not necessary, but it might be necessary
		// for collecting statistics in some cases. Default is false.
		bool send_redundant_have;

		// if this is true, outgoing bitfields will never be fuil. If the
		// client is seed, a few bits will be set to 0, and later filled
		// in with have messages. This is to prevent certain ISPs
		// from stopping people from seeding.
		bool lazy_bitfields;

		// if a peer is uninteresting and uninterested for longer
		// than this number of seconds, it will be disconnected.
		// default is 10 minutes
		int inactivity_timeout;

		// the number of seconds between chokes/unchokes
		int unchoke_interval;

		// the number of unchoke intervals between
		// optimistic unchokes
		int optimistic_unchoke_multiplier;

		// if this is set, this IP will be reported do the
		// tracker in the ip= parameter.
		address announce_ip;

		// the num want sent to trackers
		int num_want;

		// while we have fewer pieces than this, pick
		// random pieces instead of rarest first.
		int initial_picker_threshold;

		// the number of allowed pieces to send to peers
		// that supports the fast extensions
		int allowed_fast_set_size;

		// the maximum number of bytes a connection may have
		// pending in the disk write queue before its download
		// rate is being throttled. This prevents fast downloads
		// to slow medias to allocate more and more memory
		// indefinitely. This should be set to at least 32 kB
		// to not completely disrupt normal downloads.
		int max_outstanding_disk_bytes_per_connection;

		// the number of seconds to wait for a handshake
		// response from a peer. If no response is received
		// within this time, the peer is disconnected.
		int handshake_timeout;

#ifndef TORRENT_DISABLE_DHT
		// while this is true, the dht will note be used unless the
		// tracker is online
		bool use_dht_as_fallback;
#endif

		// if this is true, the piece hashes will be freed, in order
		// to save memory, once the torrent is seeding. This will
		// make the get_torrent_info() function to return an incomplete
		// torrent object that cannot be passed back to add_torrent()
		bool free_torrent_hashes;
	};

#ifndef TORRENT_DISABLE_DHT
	struct dht_settings
	{
		dht_settings()
			: max_peers_reply(50)
			, search_branching(5)
			, service_port(0)
			, max_fail_count(20)
		{}

		// the maximum number of peers to send in a
		// reply to get_peers
		int max_peers_reply;

		// the number of simultanous "connections" when
		// searching the DHT.
		int search_branching;

		// the listen port for the dht. This is a UDP port.
		// zero means use the same as the tcp interface
		int service_port;

		// the maximum number of times a node can fail
		// in a row before it is removed from the table.
		int max_fail_count;
	};
#endif

#ifndef TORRENT_DISABLE_ENCRYPTION

	struct pe_settings
	{
		pe_settings()
			: out_enc_policy(enabled)
			, in_enc_policy(enabled)
			, allowed_enc_level(both)
			, prefer_rc4(false)
		{}

		enum enc_policy
		{
			forced,  // disallow non encrypted connections
			enabled, // allow encrypted and non encrypted connections
			disabled // disallow encrypted connections
		};

		enum enc_level
		{
			plaintext, // use only plaintext encryption
			rc4, // use only rc4 encryption
			both // allow both
		};

		enc_policy out_enc_policy;
		enc_policy in_enc_policy;

		enc_level allowed_enc_level;
		// if the allowed encryption level is both, setting this to
		// true will prefer rc4 if both methods are offered, plaintext
		// otherwise
		bool prefer_rc4;
	};
#endif

}

#endif
<|endoftext|>


<commit_before>// -*- c++ -*-
/********************************************************************
 * AUTHORS: Vijay Ganesh
 *
 * BEGIN DATE: November, 2005
 *
 * LICENSE: Please view LICENSE file in the home dir of this Program
 ********************************************************************/

#include <assert.h>
#include <math.h>
#include "../AST/AST.h"
#include "../STPManager/STPManager.h"
#include "AbsRefine_CounterExample.h"

namespace BEEV
{
  /******************************************************************
   * Abstraction Refinement related functions
   ******************************************************************/

  /******************************************************************
   * ARRAY READ ABSTRACTION REFINEMENT
   *
   * SATBased_ArrayReadRefinement()
   *
   * What it really does is, for each array, loop over each index i.
   * inside that loop, it finds all the true and false axioms with i
   * as first index.  When it's got them all, it adds the false axioms
   * to the formula and re-solves, and returns if the result is
   * correct.  Otherwise, it goes on to the next index.
   *
   * If it gets through all the indices without a correct result
   * (which I think is impossible), it then solves with all the true
   * axioms, too.
   *
   * This is not the most obvious way to do it, and I don't know how
   * it compares with other approaches (e.g., one false axiom at a
   * time or all the false axioms each time).
   *****************************************************************/
  SOLVER_RETURN_TYPE
  AbsRefine_CounterExample::
  SATBased_ArrayReadRefinement(SATSolver& SatSolver,
                               const ASTNode& inputAlreadyInSAT,
                               const ASTNode& original_input,
                               ToSATBase* tosat) {

	ASTVec FalseAxiomsVec, RemainingAxiomsVec;

	// NB. Because we stop this timer before entering the SAT solver, the count
	// it produces isn't the number of times Array Read Refinement was entered.
	bm->GetRunTimes()->start(RunTimes::ArrayReadRefinement);

    //in these loops we try to construct Leibnitz axioms and add it to
    //the solve(). We add only those axioms that are false in the
    //current counterexample. we keep adding the axioms until there
    //are no more axioms to add
    //
    //for each array, fetch its list of indices seen so far
    for (ASTNodeToVecMap::const_iterator
           iset = ArrayTransform->ArrayName_ReadIndicesMap()->begin(),
           iset_end = ArrayTransform->ArrayName_ReadIndicesMap()->end();
         iset != iset_end; iset++)
      {
    	const ASTNode& ArrName = iset->first;
    	const ASTVec& listOfIndices = iset->second;

    	// Make a vector of the read symbols.
    	ASTVec read_node_symbols;
    	read_node_symbols.reserve(listOfIndices.size());

    	vector<Kind> jKind;
    	jKind.reserve(listOfIndices.size());

    	vector<ASTNode> concreteIndexes;
    	concreteIndexes.reserve(listOfIndices.size());

    	vector<ASTNode> concreteValues;
    	concreteValues.reserve(listOfIndices.size());

    	for (int i = 0; i < listOfIndices.size(); i++)
    	{
        	const ASTNode& the_index = listOfIndices[i];

        	ASTNode arr_read =
              bm->CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index);

        	ASTNode arrsym = ArrayTransform->ArrayRead_SymbolMap(arr_read);
        	assert ((SYMBOL == arrsym.GetKind() || BVCONST == arrsym.GetKind()));

        	read_node_symbols.push_back(arrsym);
        	jKind.push_back(listOfIndices[i].GetKind());

        	concreteIndexes.push_back(TermToConstTermUsingModel(the_index));
        	concreteValues.push_back(TermToConstTermUsingModel(arrsym));
    	}

        //loop over the list of indices for the array and create LA,
        //and add to inputAlreadyInSAT
        for (int i = 0; i < listOfIndices.size(); i++)
          {
        	const ASTNode& index_i = listOfIndices[i];
        	const Kind iKind = index_i.GetKind();

            // Create all distinct pairs of indexes.
            for (int j = i+1; j < listOfIndices.size(); j++)
              {
            	const ASTNode& index_j = listOfIndices[j];

            	// If the index is a constant, and different, then there's no reason to check.
            	// Sometimes we get the same index stored multiple times in the array. Not sure why...
            	if (BVCONST == iKind && jKind[j] == BVCONST && index_i != index_j)
            	{
            		continue;
            	}

            	//prepare for SAT LOOP
                //first construct the antecedent for the LA axiom
                ASTNode eqOfIndices =
                  (exprless(index_i, index_j)) ?
                  simp->CreateSimplifiedEQ(index_i, index_j) :
                  simp->CreateSimplifiedEQ(index_j, index_i);

                if (ASTFalse == eqOfIndices)
                	continue; // shortuct.

                ASTNode eqOfReads = simp->CreateSimplifiedEQ(read_node_symbols[i], read_node_symbols[j]);
                //construct appropriate Leibnitz axiom
                ASTNode LeibnitzAxiom =
                  bm->CreateNode(IMPLIES, eqOfIndices, eqOfReads);
                if (concreteIndexes[i] == concreteIndexes[j] && concreteValues[i] != concreteValues[j])
                  {
                    FalseAxiomsVec.push_back(LeibnitzAxiom);
                    //cerr << "index:" << index_i << " " <<  index_j;
                    //cerr << read_node_symbols[i];
                    //cerr << read_node_symbols[j];
                  }
                else
                  {
                    RemainingAxiomsVec.push_back(LeibnitzAxiom);
                  }
              }
            if (FalseAxiomsVec.size() > 0)
            {
				ASTNode FalseAxioms =
				  (FalseAxiomsVec.size() > 1) ?
				  bm->CreateNode(AND, FalseAxiomsVec) : FalseAxiomsVec[0];
				bm->ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms);
				SOLVER_RETURN_TYPE res2;
				bm->GetRunTimes()->stop(RunTimes::ArrayReadRefinement);
				res2 =  CallSAT_ResultCheck(SatSolver,
									  FalseAxioms,
									  original_input,
									  tosat);
				FalseAxiomsVec.clear();

				if (SOLVER_UNDECIDED != res2)
				  {
					return res2;
				  }
				bm->GetRunTimes()->start(RunTimes::ArrayReadRefinement);
            }
          }
      }
    if (RemainingAxiomsVec.size() > 0)
    {
		ASTNode RemainingAxioms =
				(RemainingAxiomsVec.size() > 1) ? bm->CreateNode(AND,
						RemainingAxiomsVec) : RemainingAxiomsVec[0];
		bm->ASTNodeStats("adding remaining readaxioms to SAT: ",
				RemainingAxioms);
		bm->GetRunTimes()->stop(RunTimes::ArrayReadRefinement);
		return CallSAT_ResultCheck(SatSolver, RemainingAxioms, original_input,
				tosat);
	}
	bm->GetRunTimes()->stop(RunTimes::ArrayReadRefinement);
    return SOLVER_UNDECIDED;
  } //end of SATBased_ArrayReadRefinement

  /******************************************************************
   * ARRAY WRITE ABSTRACTION REFINEMENT
   *
   * FIXME: Write Detailed Comment
   *****************************************************************/
  SOLVER_RETURN_TYPE
  AbsRefine_CounterExample::
  SATBased_ArrayWriteRefinement(SATSolver& SatSolver,
                                const ASTNode& original_input,
                                ToSATBase *tosat
                              )
  {
    ASTNode writeAxiom;
    ASTNodeMap::const_iterator it = simp->ReadOverWriteMap()->begin();
    ASTNodeMap::const_iterator itend = simp->ReadOverWriteMap()->end();

    ASTVec FalseAxioms, RemainingAxioms;
    for (; it != itend; it++)
      {
        //Guided refinement starts here
        ClearComputeFormulaMap();
        writeAxiom = Create_ArrayWriteAxioms(it->first, it->second);
        if (ASTFalse == ComputeFormulaUsingModel(writeAxiom))
          {
            writeAxiom = ArrayTransform->TransformFormula_TopLevel(writeAxiom);
            FalseAxioms.push_back(writeAxiom);
          }
        else
          {
            writeAxiom = ArrayTransform->TransformFormula_TopLevel(writeAxiom);
            RemainingAxioms.push_back(writeAxiom);
          }
      }

    SOLVER_RETURN_TYPE res2 = SOLVER_UNDECIDED;
    if (FalseAxioms.size() > 0)
    {
		writeAxiom = (FalseAxioms.size() != 1) ? bm->CreateNode(AND,
				FalseAxioms) : FalseAxioms[0];
		bm->ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom);
		res2 = CallSAT_ResultCheck(SatSolver, writeAxiom, original_input, tosat);
	}

    if (SOLVER_UNDECIDED != res2)
      {
        return res2;
      }

    if (RemainingAxioms.size() > 0)
    {
		writeAxiom =
		  (RemainingAxioms.size() != 1) ?
		  bm->CreateNode(AND, RemainingAxioms) : RemainingAxioms[0];
		bm->ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom);
		res2 = CallSAT_ResultCheck(SatSolver,
								   writeAxiom,
								   original_input,
								   tosat);
    }
    return res2;
  } //end of SATBased_ArrayWriteRefinement

  //Creates Array Write Axioms
  ASTNode
  AbsRefine_CounterExample::Create_ArrayWriteAxioms(const ASTNode& term,
                                                    const ASTNode& newvar)
  {
    if (READ != term.GetKind() && WRITE != term[0].GetKind())
      {
        FatalError("Create_ArrayWriteAxioms: "\
                   "Input must be a READ over a WRITE", term);
      }

    ASTNode lhs = newvar;
    ASTNode rhs = term;
    ASTNode arraywrite_axiom = simp->CreateSimplifiedEQ(lhs, rhs);
    return arraywrite_axiom;
  }//end of Create_ArrayWriteAxioms()

};// end of namespace BEEV
<commit_msg>Fix. Without a CallSAT_Result check call sometimes we get the wrong result. No idea why yet.<commit_after>// -*- c++ -*-
/********************************************************************
 * AUTHORS: Vijay Ganesh
 *
 * BEGIN DATE: November, 2005
 *
 * LICENSE: Please view LICENSE file in the home dir of this Program
 ********************************************************************/

#include <assert.h>
#include <math.h>
#include "../AST/AST.h"
#include "../STPManager/STPManager.h"
#include "AbsRefine_CounterExample.h"

namespace BEEV
{
  /******************************************************************
   * Abstraction Refinement related functions
   ******************************************************************/

  /******************************************************************
   * ARRAY READ ABSTRACTION REFINEMENT
   *
   * SATBased_ArrayReadRefinement()
   *
   * What it really does is, for each array, loop over each index i.
   * inside that loop, it finds all the true and false axioms with i
   * as first index.  When it's got them all, it adds the false axioms
   * to the formula and re-solves, and returns if the result is
   * correct.  Otherwise, it goes on to the next index.
   *
   * If it gets through all the indices without a correct result
   * (which I think is impossible), it then solves with all the true
   * axioms, too.
   *
   * This is not the most obvious way to do it, and I don't know how
   * it compares with other approaches (e.g., one false axiom at a
   * time or all the false axioms each time).
   *****************************************************************/
  SOLVER_RETURN_TYPE
  AbsRefine_CounterExample::
  SATBased_ArrayReadRefinement(SATSolver& SatSolver,
                               const ASTNode& inputAlreadyInSAT,
                               const ASTNode& original_input,
                               ToSATBase* tosat) {

	ASTVec FalseAxiomsVec, RemainingAxiomsVec;

	// NB. Because we stop this timer before entering the SAT solver, the count
	// it produces isn't the number of times Array Read Refinement was entered.
	bm->GetRunTimes()->start(RunTimes::ArrayReadRefinement);

    //in these loops we try to construct Leibnitz axioms and add it to
    //the solve(). We add only those axioms that are false in the
    //current counterexample. we keep adding the axioms until there
    //are no more axioms to add
    //
    //for each array, fetch its list of indices seen so far
    for (ASTNodeToVecMap::const_iterator
           iset = ArrayTransform->ArrayName_ReadIndicesMap()->begin(),
           iset_end = ArrayTransform->ArrayName_ReadIndicesMap()->end();
         iset != iset_end; iset++)
      {
    	const ASTNode& ArrName = iset->first;
    	const ASTVec& listOfIndices = iset->second;

    	// Make a vector of the read symbols.
    	ASTVec read_node_symbols;
    	read_node_symbols.reserve(listOfIndices.size());

    	vector<Kind> jKind;
    	jKind.reserve(listOfIndices.size());

    	vector<ASTNode> concreteIndexes;
    	concreteIndexes.reserve(listOfIndices.size());

    	vector<ASTNode> concreteValues;
    	concreteValues.reserve(listOfIndices.size());

    	for (int i = 0; i < listOfIndices.size(); i++)
    	{
        	const ASTNode& the_index = listOfIndices[i];

        	ASTNode arr_read =
              bm->CreateTerm(READ, ArrName.GetValueWidth(), ArrName, the_index);

        	ASTNode arrsym = ArrayTransform->ArrayRead_SymbolMap(arr_read);
        	assert ((SYMBOL == arrsym.GetKind() || BVCONST == arrsym.GetKind()));

        	read_node_symbols.push_back(arrsym);
        	jKind.push_back(listOfIndices[i].GetKind());

        	concreteIndexes.push_back(TermToConstTermUsingModel(the_index));
        	concreteValues.push_back(TermToConstTermUsingModel(arrsym));
    	}

        //loop over the list of indices for the array and create LA,
        //and add to inputAlreadyInSAT
        for (int i = 0; i < listOfIndices.size(); i++)
          {
        	const ASTNode& index_i = listOfIndices[i];
        	const Kind iKind = index_i.GetKind();

            // Create all distinct pairs of indexes.
            for (int j = i+1; j < listOfIndices.size(); j++)
              {
            	const ASTNode& index_j = listOfIndices[j];

            	// If the index is a constant, and different, then there's no reason to check.
            	// Sometimes we get the same index stored multiple times in the array. Not sure why...
            	if (BVCONST == iKind && jKind[j] == BVCONST && index_i != index_j)
            	{
            		continue;
            	}

            	//prepare for SAT LOOP
                //first construct the antecedent for the LA axiom
                ASTNode eqOfIndices =
                  (exprless(index_i, index_j)) ?
                  simp->CreateSimplifiedEQ(index_i, index_j) :
                  simp->CreateSimplifiedEQ(index_j, index_i);

                if (ASTFalse == eqOfIndices)
                	continue; // shortuct.

                ASTNode eqOfReads = simp->CreateSimplifiedEQ(read_node_symbols[i], read_node_symbols[j]);
                //construct appropriate Leibnitz axiom
                ASTNode LeibnitzAxiom =
                  bm->CreateNode(IMPLIES, eqOfIndices, eqOfReads);
                if (concreteIndexes[i] == concreteIndexes[j] && concreteValues[i] != concreteValues[j])
                  {
                    FalseAxiomsVec.push_back(LeibnitzAxiom);
                    //cerr << "index:" << index_i << " " <<  index_j;
                    //cerr << read_node_symbols[i];
                    //cerr << read_node_symbols[j];
                  }
                else
                  {
                    RemainingAxiomsVec.push_back(LeibnitzAxiom);
                  }
              }
            if (FalseAxiomsVec.size() > 0)
            {
				ASTNode FalseAxioms =
				  (FalseAxiomsVec.size() > 1) ?
				  bm->CreateNode(AND, FalseAxiomsVec) : FalseAxiomsVec[0];
				bm->ASTNodeStats("adding false readaxioms to SAT: ", FalseAxioms);
				SOLVER_RETURN_TYPE res2;
				bm->GetRunTimes()->stop(RunTimes::ArrayReadRefinement);
				res2 =  CallSAT_ResultCheck(SatSolver,
									  FalseAxioms,
									  original_input,
									  tosat);
				FalseAxiomsVec.clear();

				if (SOLVER_UNDECIDED != res2)
				  {
					return res2;
				  }
				bm->GetRunTimes()->start(RunTimes::ArrayReadRefinement);
            }
          }
      }
    if (RemainingAxiomsVec.size() > 0)
    {
		ASTNode RemainingAxioms =
				(RemainingAxiomsVec.size() > 1) ? bm->CreateNode(AND,
						RemainingAxiomsVec) : RemainingAxiomsVec[0];
		bm->ASTNodeStats("adding remaining readaxioms to SAT: ",
				RemainingAxioms);
		bm->GetRunTimes()->stop(RunTimes::ArrayReadRefinement);
		return CallSAT_ResultCheck(SatSolver, RemainingAxioms, original_input,
				tosat);
	}
	bm->GetRunTimes()->stop(RunTimes::ArrayReadRefinement);
    return SOLVER_UNDECIDED;
  } //end of SATBased_ArrayReadRefinement

  /******************************************************************
   * ARRAY WRITE ABSTRACTION REFINEMENT
   *
   * FIXME: Write Detailed Comment
   *****************************************************************/
  SOLVER_RETURN_TYPE
  AbsRefine_CounterExample::
  SATBased_ArrayWriteRefinement(SATSolver& SatSolver,
                                const ASTNode& original_input,
                                ToSATBase *tosat
                              )
  {
    ASTNode writeAxiom;
    ASTNodeMap::const_iterator it = simp->ReadOverWriteMap()->begin();
    ASTNodeMap::const_iterator itend = simp->ReadOverWriteMap()->end();

    ASTVec FalseAxioms, RemainingAxioms;
    RemainingAxioms.push_back(ASTTrue);
    for (; it != itend; it++)
      {
        //Guided refinement starts here
        ClearComputeFormulaMap();
        writeAxiom = Create_ArrayWriteAxioms(it->first, it->second);
        if (ASTFalse == ComputeFormulaUsingModel(writeAxiom))
          {
            writeAxiom = ArrayTransform->TransformFormula_TopLevel(writeAxiom);
            FalseAxioms.push_back(writeAxiom);
          }
        else
          {
            writeAxiom = ArrayTransform->TransformFormula_TopLevel(writeAxiom);
            RemainingAxioms.push_back(writeAxiom);
          }
      }

    SOLVER_RETURN_TYPE res2 = SOLVER_UNDECIDED;
    if (FalseAxioms.size() > 0)
    {
		writeAxiom = (FalseAxioms.size() != 1) ? bm->CreateNode(AND,
				FalseAxioms) : FalseAxioms[0];
		bm->ASTNodeStats("adding false writeaxiom to SAT: ", writeAxiom);
		res2 = CallSAT_ResultCheck(SatSolver, writeAxiom, original_input, tosat);
	}

    if (SOLVER_UNDECIDED != res2)
      {
        return res2;
      }

    if (RemainingAxioms.size() > 0)
    {
		writeAxiom =
		  (RemainingAxioms.size() != 1) ?
		  bm->CreateNode(AND, RemainingAxioms) : RemainingAxioms[0];
		bm->ASTNodeStats("adding remaining writeaxiom to SAT: ", writeAxiom);
		res2 = CallSAT_ResultCheck(SatSolver,
								   writeAxiom,
								   original_input,
								   tosat);
    }
    return res2;
  } //end of SATBased_ArrayWriteRefinement

  //Creates Array Write Axioms
  ASTNode
  AbsRefine_CounterExample::Create_ArrayWriteAxioms(const ASTNode& term,
                                                    const ASTNode& newvar)
  {
    if (READ != term.GetKind() && WRITE != term[0].GetKind())
      {
        FatalError("Create_ArrayWriteAxioms: "\
                   "Input must be a READ over a WRITE", term);
      }

    ASTNode lhs = newvar;
    ASTNode rhs = term;
    ASTNode arraywrite_axiom = simp->CreateSimplifiedEQ(lhs, rhs);
    return arraywrite_axiom;
  }//end of Create_ArrayWriteAxioms()

};// end of namespace BEEV
<|endoftext|>


<commit_before>// This file is part of the "x0" project, http://github.com/christianparpart/x0>
//   (c) 2009-2017 Christian Parpart <christian@parpart.family>
//
// Licensed under the MIT License (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of
// the License at: http://opensource.org/licenses/MIT

#include <xzero/io/LocalFile.h>
#include <xzero/io/LocalFileRepository.h>
#include <xzero/io/MemoryMap.h>
#include <xzero/io/FileDescriptor.h>
#include <xzero/MimeTypes.h>
#include <xzero/RuntimeError.h>
#include <xzero/sysconfig.h>

#include <fstream>
#include <ctime>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

namespace xzero {

LocalFile::LocalFile(LocalFileRepository& repo,
                     const std::string& path,
                     const std::string& mimetype)
    : File(path, mimetype),
      repo_(repo),
      stat_(),
      etag_() {
  update();
}

LocalFile::~LocalFile() {
}

size_t LocalFile::size() const noexcept {
  return stat_.st_size;
}

time_t LocalFile::mtime() const noexcept {
  return stat_.st_mtime;
}

size_t LocalFile::inode() const noexcept {
  return stat_.st_ino;
}

bool LocalFile::isRegular() const noexcept {
  return S_ISREG(stat_.st_mode);
}

bool LocalFile::isDirectory() const noexcept {
  return S_ISDIR(stat_.st_mode);
}

bool LocalFile::isExecutable() const noexcept {
  return stat_.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH);
}

const std::string& LocalFile::etag() const {
  // compute ETag response header value on-demand
  if (etag_.empty()) {
    size_t count = 0;
    Buffer buf(256);
    buf.push_back('"');

    if (repo_.etagConsiderMTime_) {
      if (count++) buf.push_back('-');
      buf.push_back(mtime());
    }

    if (repo_.etagConsiderSize_) {
      if (count++) buf.push_back('-');
      buf.push_back(size());
    }

    if (repo_.etagConsiderINode_) {
      if (count++) buf.push_back('-');
      buf.push_back(inode());
    }

    buf.push_back('"');

    etag_ = buf.str();
  }

  return etag_;
}

void LocalFile::update() {
  int rv = stat(path().c_str(), &stat_);

  if (rv < 0) {
    setErrorCode(errno);
  } else {
    setErrorCode(0);

    if (isDirectory()) {
      mimetype_ = "inode/directory";
    }
  }
}

int LocalFile::createPosixChannel(OpenFlags oflags, int mode) {
  if (mode) {
    return ::open(path().c_str(), to_posix(oflags), mode);
  } else {
    return ::open(path().c_str(), to_posix(oflags));
  }
}

std::unique_ptr<MemoryMap> LocalFile::createMemoryMap(bool rw) {
  // use FileDescriptor for auto-closing here, in case of exceptions
  FileDescriptor fd = ::open(path().c_str(), rw ? O_RDWR : O_RDONLY);
  if (fd < 0)
    RAISE_ERRNO(errno);

  return std::unique_ptr<MemoryMap>(new MemoryMap(fd, 0, size(), rw));
}

std::shared_ptr<LocalFile> LocalFile::get(const std::string& path) {
  static MimeTypes mimetypes;
  static LocalFileRepository repo(mimetypes, "/", true, true, false);
  return std::static_pointer_cast<LocalFile>(repo.getFile(path));
}

} // namespace xzero
<commit_msg>[xzero] directory mimetype adjust<commit_after>// This file is part of the "x0" project, http://github.com/christianparpart/x0>
//   (c) 2009-2017 Christian Parpart <christian@parpart.family>
//
// Licensed under the MIT License (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of
// the License at: http://opensource.org/licenses/MIT

#include <xzero/io/LocalFile.h>
#include <xzero/io/LocalFileRepository.h>
#include <xzero/io/MemoryMap.h>
#include <xzero/io/FileDescriptor.h>
#include <xzero/MimeTypes.h>
#include <xzero/RuntimeError.h>
#include <xzero/sysconfig.h>

#include <fstream>
#include <ctime>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

namespace xzero {

LocalFile::LocalFile(LocalFileRepository& repo,
                     const std::string& path,
                     const std::string& mimetype)
    : File(path, mimetype),
      repo_(repo),
      stat_(),
      etag_() {
  update();
}

LocalFile::~LocalFile() {
}

size_t LocalFile::size() const noexcept {
  return stat_.st_size;
}

time_t LocalFile::mtime() const noexcept {
  return stat_.st_mtime;
}

size_t LocalFile::inode() const noexcept {
  return stat_.st_ino;
}

bool LocalFile::isRegular() const noexcept {
  return S_ISREG(stat_.st_mode);
}

bool LocalFile::isDirectory() const noexcept {
  return S_ISDIR(stat_.st_mode);
}

bool LocalFile::isExecutable() const noexcept {
  return stat_.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH);
}

const std::string& LocalFile::etag() const {
  // compute ETag response header value on-demand
  if (etag_.empty()) {
    size_t count = 0;
    Buffer buf(256);
    buf.push_back('"');

    if (repo_.etagConsiderMTime_) {
      if (count++) buf.push_back('-');
      buf.push_back(mtime());
    }

    if (repo_.etagConsiderSize_) {
      if (count++) buf.push_back('-');
      buf.push_back(size());
    }

    if (repo_.etagConsiderINode_) {
      if (count++) buf.push_back('-');
      buf.push_back(inode());
    }

    buf.push_back('"');

    etag_ = buf.str();
  }

  return etag_;
}

void LocalFile::update() {
  int rv = stat(path().c_str(), &stat_);

  if (rv < 0) {
    setErrorCode(errno);
  } else {
    setErrorCode(0);

    if (isDirectory()) {
      // XXX see https://tools.ietf.org/html/rfc2425
      mimetype_ = "text/directory";
    }
  }
}

int LocalFile::createPosixChannel(OpenFlags oflags, int mode) {
  if (mode) {
    return ::open(path().c_str(), to_posix(oflags), mode);
  } else {
    return ::open(path().c_str(), to_posix(oflags));
  }
}

std::unique_ptr<MemoryMap> LocalFile::createMemoryMap(bool rw) {
  // use FileDescriptor for auto-closing here, in case of exceptions
  FileDescriptor fd = ::open(path().c_str(), rw ? O_RDWR : O_RDONLY);
  if (fd < 0)
    RAISE_ERRNO(errno);

  return std::unique_ptr<MemoryMap>(new MemoryMap(fd, 0, size(), rw));
}

std::shared_ptr<LocalFile> LocalFile::get(const std::string& path) {
  static MimeTypes mimetypes;
  static LocalFileRepository repo(mimetypes, "/", true, true, false);
  return std::static_pointer_cast<LocalFile>(repo.getFile(path));
}

} // namespace xzero
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <vcl\Sysutils.hpp>

#include "vtkBorlandRenderWindow.h"

#include "vtkInteractorStyleSwitch.h"
#include "vtkInteractorStyleFlight.h"
#include "vtkInteractorStyleImage.h"
#include "vtkInteractorStyleUser.h"

#pragma package(smart_init)

//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TvtkBorlandRenderWindow *)
{
  new TvtkBorlandRenderWindow(NULL);
}

//---------------------------------------------------------------------------
namespace Vtkborlandrenderwindow
{
  void __fastcall PACKAGE Register()
    {
    TComponentClass classes[1] = {__classid(TvtkBorlandRenderWindow)};
    RegisterComponents("Samples", classes, 0);
    }
}

//---------------------------------------------------------------------------
__fastcall TvtkBorlandRenderWindow::TvtkBorlandRenderWindow(TComponent* Owner)
        : inherited(Owner)
{
  // Do want these
  ControlStyle << csCaptureMouse << csClickEvents << csOpaque << csDoubleClicks;
  // Don't want these
  ControlStyle >> csAcceptsControls >> csSetCaption;

  FUsevtkInteractor   = true;
  FInteractorMode     = IM_TrackballCamera;
  FInteractor         = 0;
  FOnVtkClose         = 0;
  FRenderWindow       = 0;
  FRenderer           = 0;
  FAbortCallback      = vtkAbortCallback::New();
}

//---------------------------------------------------------------------------
__fastcall TvtkBorlandRenderWindow::~TvtkBorlandRenderWindow()
{
    // Delete this first because Renderwindow has a hold on it too
  if ( FInteractor )
    {
    FInteractor->Delete();
    FInteractor = 0;
    }
  if ( FRenderer )
    {
    FRenderer->GetProps()->RemoveAllItems();
    FRenderWindow->RemoveRenderer(FRenderer);
    FRenderer->Delete();
    FRenderer = 0;
    }
  if ( FRenderWindow )
    {
    FRenderWindow->RemoveObserver(FAbortCallback);
    FRenderWindow->Delete();
    FRenderWindow = 0;
    }
  FAbortCallback->Delete();
}

//---------------------------------------------------------------------------
vtkWin32OpenGLRenderWindow * __fastcall TvtkBorlandRenderWindow::GetRenderWindow(void)
{
  if ( ! FRenderWindow )
    {
    // Stuff the renderwindow into our window
    FRenderWindow = vtkWin32OpenGLRenderWindow::New();
    FRenderWindow->AddObserver( vtkCommand::AbortCheckEvent, FAbortCallback);
    FRenderWindow->SetParentId(Parent->Handle);
    FRenderWindow->SetWindowId(Handle);
    FRenderWindow->DoubleBufferOn();
    FRenderWindow->SwapBuffersOn();
    // Frame to avoid unsightly garbage during initial
    // display which may be long when a complex scene is first rendered
    FRenderWindow->Frame();
    Invalidate();
    }
    // We create the interactor here because it makes maintenance better
  if (!FInteractor)
    {
    FInteractor = vtkWin32RenderWindowInteractor::New();
    FInteractor->SetRenderWindow(FRenderWindow);
    FInteractor->SetInstallMessageProc(false);
    SetInteractorMode(FInteractorMode);
    FInteractor->UpdateSize(Width,Height);
    FInteractor->Initialize();
    }
  return FRenderWindow;
}

//---------------------------------------------------------------------------
vtkWin32RenderWindowInteractor * __fastcall TvtkBorlandRenderWindow::GetInteractor(void)
{
  if (FRenderWindow)
    {
    if (!FInteractor)
      {
      throw Exception("Window exists but no Interactor, this shouldn't happen");
      }
    }
  else
    {
    this->GetRenderWindow();
    }
  return FInteractor;
}

//---------------------------------------------------------------------------
vtkRenderer * __fastcall TvtkBorlandRenderWindow::GetRenderer(void)
{
  if (!FRenderer)
    {
    FRenderer = vtkRenderer::New();
    GetRenderWindow()->AddRenderer(FRenderer);
    FRenderer->ResetCamera();
    DWORD  L = ColorToRGB(Color);
    float rgb[3] = { GetRValue(L)/255.0, GetGValue(L)/255.0, GetBValue(L)/255.0 };
    FRenderer->SetBackground(rgb);
    }
  return FRenderer;
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::SetInteractorMode(const vtkBorlandInteractorMode& im)
{
  if ( im <= IM_TrackballActor && im >= IM_JoystickCamera )
    {
    vtkInteractorStyleSwitch *iass = dynamic_cast<vtkInteractorStyleSwitch*>(FInteractor->GetInteractorStyle());
    if (!iass)
      {
      iass = vtkInteractorStyleSwitch::New();
      FInteractor->SetInteractorStyle(iass);
      iass->Delete();
      }

    switch ( im )
      {
      case IM_JoystickCamera: iass->SetCurrentStyleToJoystickCamera(); break;
      case IM_JoystickActor: iass->SetCurrentStyleToJoystickActor(); break;
      case IM_TrackballCamera: iass->SetCurrentStyleToTrackballCamera(); break;
      case IM_TrackballActor: iass->SetCurrentStyleToTrackballActor(); break;
      default: break;
      }
      FInteractorMode = im;
    }
    else if (im==IM_Flight)
      {
      vtkInteractorStyleFlight *iafl = dynamic_cast<vtkInteractorStyleFlight*>(FInteractor->GetInteractorStyle());
      if (!iafl)
        {
        iafl = vtkInteractorStyleFlight::New();
        FInteractor->SetInteractorStyle(iafl);
        iafl->Delete();
        }
      FInteractorMode = IM_Flight;
      }
    else if (im==IM_Image)
      {
      vtkInteractorStyleImage *iasi = dynamic_cast<vtkInteractorStyleImage*>(FInteractor->GetInteractorStyle());
      if (!iasi)
        {
        iasi = vtkInteractorStyleImage::New();
        FInteractor->SetInteractorStyle(iasi);
        iasi->Delete();
        }
      FInteractorMode = IM_Image;
      }
    else if (im==IM_User)
      {
      vtkInteractorStyleUser *iasu = dynamic_cast<vtkInteractorStyleUser*>(FInteractor->GetInteractorStyle());
      if (!iasu)
        {
        iasu = vtkInteractorStyleUser::New();
        FInteractor->SetInteractorStyle(iasu);
        iasu->Delete();
        }
      FInteractorMode = IM_User;
      }
    else
      {
      return;
      }
}

//---------------------------------------------------------------------------
// Paint
//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::Paint(void)
{
  if (FRenderWindow)
    {
    try
      {
      FRenderWindow->Render();
      }
    catch (...)
      {
      // Some error trap should occurr here
      ShowMessage("An exception occurred whilst rendering");
      }
    }
  else
    { // Design time or before RenderWindow creation
    inherited::Paint();
    }
}

//---------------------------------------------------------------------------
// Event handlers
//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
  if (!FRenderWindow)
    {
    inherited::Dispatch(&Message);
    }
  else
    {
    Message.Result = 1; // No, but thanks for asking.
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMGetDlgCode(TMessage &Message)
{
  Message.Result = DLGC_WANTARROWS;
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMChar(TWMKey &Message)
{
  switch (Message.CharCode)
    {
    case 'e':
    case 'E':
    case 'q':
    case 'Q': if (!FOnVtkClose || (FOnVtkClose && FOnVtkClose(this)))
                {
                FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
                }
              break;
    default:  FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMKeyDown(TWMKey &Message)
{
  FInteractor->OnKeyDown(Handle,Message.CharCode, 0, 0);
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMKeyUp(TWMKey &Message)
{
  FInteractor->OnKeyUp(Handle,Message.CharCode, 0, 0);
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::MouseMove(TShiftState shift, int x, int y )
{
  if(this->OnMouseMove && shift.Contains(ssCtrl))
    {
    this->OnMouseMove(this,shift,x,y);
    return;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (shift.Contains(ssShift)) flags += MK_SHIFT;
    if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
    FInteractor->OnMouseMove(Handle, flags, x, y );
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::MouseDown(TMouseButton button, TShiftState shift, int x, int y )
{
  if (::GetFocus()!=Handle) SetFocus();

  if(this->OnMouseDown && shift.Contains(ssCtrl))
    {
    this->OnMouseDown(this,button,shift,x,y);
    return;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (shift.Contains(ssShift)) flags += MK_SHIFT;
    if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
    switch (button)
      {
      case mbLeft:   FInteractor->OnLButtonDown(Handle, flags, x,y); break;
      case mbRight:  FInteractor->OnRButtonDown(Handle, flags, x,y); break;
      case mbMiddle: FInteractor->OnMButtonDown(Handle, flags, x,y); break;
      }
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::MouseUp(TMouseButton button, TShiftState shift, int x, int y )
{
  if(this->OnMouseUp  && shift.Contains(ssCtrl))
    {
    this->OnMouseUp(this,button,shift,x,y);
    return;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (shift.Contains(ssShift)) flags += MK_SHIFT;
    if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
    switch (button)
      {
      case mbLeft:   FInteractor->OnLButtonUp(Handle, flags, x,y); break;
      case mbRight:  FInteractor->OnRButtonUp(Handle, flags, x,y); break;
      case mbMiddle: FInteractor->OnMButtonUp(Handle, flags, x,y); break;
      }
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::Resize(void)
{
  if (FInteractor)
    {
    FInteractor->OnSize(this->Handle, 0, this->Width, this->Height);
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMTimer(TWMTimer &Message)
{
  if (FInteractor)
    {
    FInteractor->OnTimer(Handle,Message.TimerID);
    }
}

//---------------------------------------------------------------------------
bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelDown(TShiftState Shift, const TPoint &MousePos)
{
  bool result;
  if (this->OnMouseWheelDown && Shift.Contains(ssCtrl))
    {
    this->OnMouseWheelDown(this,Shift,MousePos,result);
    return result;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
    if (Shift.Contains(ssCtrl))  { flags += MK_CONTROL; }
    FInteractor->OnMouseWheelBackward(Handle, flags, MousePos.x,MousePos.y);
    result = true;
    }
  return result;
}

//---------------------------------------------------------------------------
bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelUp(TShiftState Shift, const TPoint &MousePos)
{
  bool result;
  if (this->OnMouseWheelUp && Shift.Contains(ssCtrl))
    {
    this->OnMouseWheelUp(this,Shift,MousePos,result);
    return result;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
    if (Shift.Contains(ssCtrl))  { flags += MK_CONTROL; }
    FInteractor->OnMouseWheelForward(Handle, flags, MousePos.x,MousePos.y);
    result = true;
    }
  return result;
}

<commit_msg>COMP: update Borland example file per Luca Picello to the vtk-developers mailing list...<commit_after>//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include <vcl\Sysutils.hpp>

#include "vtkBorlandRenderWindow.h"

#include "vtkInteractorStyleSwitch.h"
#include "vtkInteractorStyleFlight.h"
#include "vtkInteractorStyleImage.h"
#include "vtkInteractorStyleUser.h"

#pragma package(smart_init)

//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TvtkBorlandRenderWindow *)
{
  new TvtkBorlandRenderWindow(NULL);
}

//---------------------------------------------------------------------------
namespace Vtkborlandrenderwindow
{
  void __fastcall PACKAGE Register()
    {
    TComponentClass classes[1] = {__classid(TvtkBorlandRenderWindow)};
    RegisterComponents("Samples", classes, 0);
    }
}

//---------------------------------------------------------------------------
__fastcall TvtkBorlandRenderWindow::TvtkBorlandRenderWindow(TComponent* Owner)
        : inherited(Owner)
{
  // Do want these
  ControlStyle << csCaptureMouse << csClickEvents << csOpaque << csDoubleClicks;
  // Don't want these
  ControlStyle >> csAcceptsControls >> csSetCaption;

  FUsevtkInteractor   = true;
  FInteractorMode     = IM_TrackballCamera;
  FInteractor         = 0;
  FOnVtkClose         = 0;
  FRenderWindow       = 0;
  FRenderer           = 0;
  FAbortCallback      = vtkAbortCallback::New();
}

//---------------------------------------------------------------------------
__fastcall TvtkBorlandRenderWindow::~TvtkBorlandRenderWindow()
{
    // Delete this first because Renderwindow has a hold on it too
  if ( FInteractor )
    {
    FInteractor->Delete();
    FInteractor = 0;
    }
  if ( FRenderer )
    {
    FRenderer->GetProps()->RemoveAllItems();
    FRenderWindow->RemoveRenderer(FRenderer);
    FRenderer->Delete();
    FRenderer = 0;
    }
  if ( FRenderWindow )
    {
    FRenderWindow->RemoveObserver(FAbortCallback);
    FRenderWindow->Delete();
    FRenderWindow = 0;
    }
  FAbortCallback->Delete();
}

//---------------------------------------------------------------------------
vtkWin32OpenGLRenderWindow * __fastcall TvtkBorlandRenderWindow::GetRenderWindow(void)
{
  if ( ! FRenderWindow )
    {
    // Stuff the renderwindow into our window
    FRenderWindow = vtkWin32OpenGLRenderWindow::New();
    FRenderWindow->AddObserver( vtkCommand::AbortCheckEvent, FAbortCallback);
    FRenderWindow->SetParentId(Parent->Handle);
    FRenderWindow->SetWindowId(Handle);
    FRenderWindow->DoubleBufferOn();
    FRenderWindow->SwapBuffersOn();
    // Frame to avoid unsightly garbage during initial
    // display which may be long when a complex scene is first rendered
    FRenderWindow->Frame();
    Invalidate();
    }
    // We create the interactor here because it makes maintenance better
  if (!FInteractor)
    {
    FInteractor = vtkWin32RenderWindowInteractor::New();
    FInteractor->SetRenderWindow(FRenderWindow);
    FInteractor->SetInstallMessageProc(false);
    SetInteractorMode(FInteractorMode);
    FInteractor->UpdateSize(Width,Height);
    FInteractor->Initialize();
    }
  return FRenderWindow;
}

//---------------------------------------------------------------------------
vtkWin32RenderWindowInteractor * __fastcall TvtkBorlandRenderWindow::GetInteractor(void)
{
  if (FRenderWindow)
    {
    if (!FInteractor)
      {
      throw Exception("Window exists but no Interactor, this shouldn't happen");
      }
    }
  else
    {
    this->GetRenderWindow();
    }
  return FInteractor;
}

//---------------------------------------------------------------------------
vtkRenderer * __fastcall TvtkBorlandRenderWindow::GetRenderer(void)
{
  if (!FRenderer)
    {
    FRenderer = vtkRenderer::New();
    GetRenderWindow()->AddRenderer(FRenderer);
    FRenderer->ResetCamera();
    DWORD  L = ColorToRGB(Color);
    double rgb[3] = { GetRValue(L)/255.0, GetGValue(L)/255.0, GetBValue(L)/255.0 };
    FRenderer->SetBackground(rgb);
    }
  return FRenderer;
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::SetInteractorMode(const vtkBorlandInteractorMode& im)
{
  if ( im <= IM_TrackballActor && im >= IM_JoystickCamera )
    {
    vtkInteractorStyleSwitch *iass = dynamic_cast<vtkInteractorStyleSwitch*>(FInteractor->GetInteractorStyle());
    if (!iass)
      {
      iass = vtkInteractorStyleSwitch::New();
      FInteractor->SetInteractorStyle(iass);
      iass->Delete();
      }

    switch ( im )
      {
      case IM_JoystickCamera: iass->SetCurrentStyleToJoystickCamera(); break;
      case IM_JoystickActor: iass->SetCurrentStyleToJoystickActor(); break;
      case IM_TrackballCamera: iass->SetCurrentStyleToTrackballCamera(); break;
      case IM_TrackballActor: iass->SetCurrentStyleToTrackballActor(); break;
      default: break;
      }
      FInteractorMode = im;
    }
    else if (im==IM_Flight)
      {
      vtkInteractorStyleFlight *iafl = dynamic_cast<vtkInteractorStyleFlight*>(FInteractor->GetInteractorStyle());
      if (!iafl)
        {
        iafl = vtkInteractorStyleFlight::New();
        FInteractor->SetInteractorStyle(iafl);
        iafl->Delete();
        }
      FInteractorMode = IM_Flight;
      }
    else if (im==IM_Image)
      {
      vtkInteractorStyleImage *iasi = dynamic_cast<vtkInteractorStyleImage*>(FInteractor->GetInteractorStyle());
      if (!iasi)
        {
        iasi = vtkInteractorStyleImage::New();
        FInteractor->SetInteractorStyle(iasi);
        iasi->Delete();
        }
      FInteractorMode = IM_Image;
      }
    else if (im==IM_User)
      {
      vtkInteractorStyleUser *iasu = dynamic_cast<vtkInteractorStyleUser*>(FInteractor->GetInteractorStyle());
      if (!iasu)
        {
        iasu = vtkInteractorStyleUser::New();
        FInteractor->SetInteractorStyle(iasu);
        iasu->Delete();
        }
      FInteractorMode = IM_User;
      }
    else
      {
      return;
      }
}

//---------------------------------------------------------------------------
// Paint
//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::Paint(void)
{
  if (FRenderWindow)
    {
    try
      {
      FRenderWindow->Render();
      }
    catch (...)
      {
      // Some error trap should occurr here
      ShowMessage("An exception occurred whilst rendering");
      }
    }
  else
    { // Design time or before RenderWindow creation
    inherited::Paint();
    }
}

//---------------------------------------------------------------------------
// Event handlers
//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMEraseBkgnd(TWMEraseBkgnd &Message)
{
  if (!FRenderWindow)
    {
    inherited::Dispatch(&Message);
    }
  else
    {
    Message.Result = 1; // No, but thanks for asking.
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMGetDlgCode(TMessage &Message)
{
  Message.Result = DLGC_WANTARROWS;
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMChar(TWMKey &Message)
{
  switch (Message.CharCode)
    {
    case 'e':
    case 'E':
    case 'q':
    case 'Q': if (!FOnVtkClose || (FOnVtkClose && FOnVtkClose(this)))
                {
                FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
                }
              break;
    default:  FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMKeyDown(TWMKey &Message)
{
  FInteractor->OnKeyDown(Handle,Message.CharCode, 0, 0);
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMKeyUp(TWMKey &Message)
{
  FInteractor->OnKeyUp(Handle,Message.CharCode, 0, 0);
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::MouseMove(TShiftState shift, int x, int y )
{
  if(this->OnMouseMove && shift.Contains(ssCtrl))
    {
    this->OnMouseMove(this,shift,x,y);
    return;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (shift.Contains(ssShift)) flags += MK_SHIFT;
    if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
    FInteractor->OnMouseMove(Handle, flags, x, y );
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::MouseDown(TMouseButton button, TShiftState shift, int x, int y )
{
  if (::GetFocus()!=Handle) SetFocus();

  if(this->OnMouseDown && shift.Contains(ssCtrl))
    {
    this->OnMouseDown(this,button,shift,x,y);
    return;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (shift.Contains(ssShift)) flags += MK_SHIFT;
    if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
    switch (button)
      {
      case mbLeft:   FInteractor->OnLButtonDown(Handle, flags, x,y); break;
      case mbRight:  FInteractor->OnRButtonDown(Handle, flags, x,y); break;
      case mbMiddle: FInteractor->OnMButtonDown(Handle, flags, x,y); break;
      }
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::MouseUp(TMouseButton button, TShiftState shift, int x, int y )
{
  if(this->OnMouseUp  && shift.Contains(ssCtrl))
    {
    this->OnMouseUp(this,button,shift,x,y);
    return;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (shift.Contains(ssShift)) flags += MK_SHIFT;
    if (shift.Contains(ssCtrl))  flags += MK_CONTROL;
    switch (button)
      {
      case mbLeft:   FInteractor->OnLButtonUp(Handle, flags, x,y); break;
      case mbRight:  FInteractor->OnRButtonUp(Handle, flags, x,y); break;
      case mbMiddle: FInteractor->OnMButtonUp(Handle, flags, x,y); break;
      }
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::Resize(void)
{
  if (FInteractor)
    {
    FInteractor->OnSize(this->Handle, 0, this->Width, this->Height);
    }
}

//---------------------------------------------------------------------------
void __fastcall TvtkBorlandRenderWindow::WMTimer(TWMTimer &Message)
{
  if (FInteractor)
    {
    FInteractor->OnTimer(Handle,Message.TimerID);
    }
}

//---------------------------------------------------------------------------
bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelDown(TShiftState Shift, const TPoint &MousePos)
{
  bool result;
  if (this->OnMouseWheelDown && Shift.Contains(ssCtrl))
    {
    this->OnMouseWheelDown(this,Shift,MousePos,result);
    return result;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
    if (Shift.Contains(ssCtrl))  { flags += MK_CONTROL; }
    FInteractor->OnMouseWheelBackward(Handle, flags, MousePos.x,MousePos.y);
    result = true;
    }
  return result;
}

//---------------------------------------------------------------------------
bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelUp(TShiftState Shift, const TPoint &MousePos)
{
  bool result;
  if (this->OnMouseWheelUp && Shift.Contains(ssCtrl))
    {
    this->OnMouseWheelUp(this,Shift,MousePos,result);
    return result;
    }

  if (FInteractor && FUsevtkInteractor)
    {
    int flags = 0;
    if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
    if (Shift.Contains(ssCtrl))  { flags += MK_CONTROL; }
    FInteractor->OnMouseWheelForward(Handle, flags, MousePos.x,MousePos.y);
    result = true;
    }
  return result;
}

<|endoftext|>


<commit_before>/*
Copyright 2011 Google Inc. 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 obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Author: lode.vandevenne@gmail.com (Lode Vandevenne)
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
*/

/*
Bounded package merge algorithm, based on the paper
"A Fast and Space-Economical Algorithm for Length-Limited Coding
Jyrki Katajainen, Alistair Moffat, Andrew Turpin".
*/

/*Modified by Felix Hanau*/

#include "katajainen.h"
#include "util.h"

#include <stdlib.h>
#include <assert.h>
#include <algorithm>

/*
Nodes forming chains. Also used to represent leaves.
*/
typedef struct Node
{
  size_t weight;  /* Total weight (symbol count) of this chain. */
  Node* tail;  /* Previous node(s) of this chain, or 0 if none. */
  int count;  /* Leaf symbol index, or number of leaves before this chain. */
}
#if defined(__GNUC__) && (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64))
__attribute__((packed)) Node;
#else
Node;
#endif

/*
Initializes a chain node with the given values and marks it as in use.
*/
static void InitNode(size_t weight, int count, Node* tail, Node* node) {
  node->weight = weight;
  node->count = count;
  node->tail = tail;
}

static void BoundaryPMfinal(Node* (*lists)[2],
                            Node* leaves, int numsymbols, Node* pool, int index) {
  int lastcount = lists[index][1]->count;  /* Count of last chain of list. */

  size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;

  if (lastcount < numsymbols && sum > leaves[lastcount].weight) {

    Node* oldchain = lists[index][1]->tail;

    lists[index][1] = pool;
    pool->count = lastcount + 1;
    pool->tail = oldchain;

  }
  else{
    lists[index][1]->tail = lists[index - 1][1];
  }
}

/*
Initializes each list with as lookahead chains the two leaves with lowest
weights.
*/
static void InitLists(
    Node* pool, const Node* leaves, int maxbits, Node* (*lists)[2]) {
  Node* node0 = pool;
  Node* node1 = pool + 1;
  InitNode(leaves[0].weight, 1, 0, node0);
  InitNode(leaves[1].weight, 2, 0, node1);
  for (int i = 0; i < maxbits; i++) {
    lists[i][0] = node0;
    lists[i][1] = node1;
  }
}

/*
Converts result of boundary package-merge to the bitlengths. The result in the
last chain of the last list contains the amount of active leaves in each list.
chain: Chain to extract the bit length from (last chain from last list).
*/
static void ExtractBitLengths(Node* chain, Node* leaves, unsigned* bitlengths) {
  //Messy, but fast
  int counts[16] = {0};
  unsigned end = 16;
  for (Node* node = chain; node; node = node->tail) {
    end--;
    counts[end] = node->count;
  }

  unsigned ptr = 15;
  unsigned value = 1;
  unsigned val = counts[15];
  while (ptr >= end) {

    for (; val > counts[ptr - 1]; val--) {
      bitlengths[leaves[val - 1].count] = value;
    }
    ptr--;
    value++;
  }
}

void ZopfliLengthLimitedCodeLengths(const size_t* frequencies, int n, int maxbits, unsigned* bitlengths) {
  int i;
  int numsymbols = 0;  /* Amount of symbols with frequency > 0. */

  /* Array of lists of chains. Each list requires only two lookahead chains at
  a time, so each list is a array of two Node*'s. */

  /* One leaf per symbol. Only numsymbols leaves will be used. */
  Node leaves[286];

  /* Initialize all bitlengths at 0. */
  memset(bitlengths, 0, n * sizeof(unsigned));

  /* Count used symbols and place them in the leaves. */
  for (i = 0; i < n; i++) {
    if (frequencies[i]) {
      leaves[numsymbols].weight = frequencies[i];
      leaves[numsymbols].count = i;  /* Index of symbol this leaf represents. */
      numsymbols++;
    }
  }

  /* Check special cases and error conditions. */
  assert((1 << maxbits) >= numsymbols); /* Error, too few maxbits to represent symbols. */
  if (numsymbols == 0) {
    return;  /* No symbols at all. OK. */
  }
  if (numsymbols == 1) {
    bitlengths[leaves[0].count] = 1;
    return;  /* Only one symbol, give it bitlength 1, not 0. OK. */
  }
  if (numsymbols == 2){
    bitlengths[leaves[0].count]++;
    bitlengths[leaves[1].count]++;
    return;
  }

  struct {
    bool operator()(const Node a, const Node b) {
      return (a.weight < b.weight);
    }
  } cmp;

  /* Sort the leaves from lightest to heaviest. */
  for (i = 0; i < numsymbols; i++) {
    leaves[i].weight = (leaves[i].weight << 9) | leaves[i].count;
  }
  std::sort(leaves, leaves + numsymbols, cmp);

  for (i = 0; i < numsymbols; i++) {
    leaves[i].weight >>= 9;
  }

  if (numsymbols - 1 < maxbits) {
    maxbits = numsymbols - 1;
  }

  /* Initialize node memory pool. */
  Node* pool;
  Node stack[8580]; //maxbits(<=15) * 2 * numsymbols(<=286), the theoretical maximum. This needs about 170kb of memory, but is much faster than a node pool using garbage collection.
  pool = stack;

  Node list[15][2];
  Node* (* lists)[2]  = ( Node* (*)[2])list;
  InitLists(pool, leaves, maxbits, lists);
  pool += 2;

  /* In the last list, 2 * numsymbols - 2 active chains need to be created. Two
  are already created in the initialization. Each BoundaryPM run creates one. */
  int numBoundaryPMRuns = 2 * numsymbols - 4;
  unsigned char stackspace[16];

  for (i = 0; i < numBoundaryPMRuns - 1; i++) {
    unsigned stackpos = 0;
    stackspace[stackpos] = maxbits - 1;

    for(;;){
      unsigned char index = stackspace[stackpos];

      int lastcount = lists[index][1]->count;  /* Count of last chain of list. */

      Node* newchain = pool++;
      Node* oldchain = lists[index][1];

      /* These are set up before the recursive calls below, so that there is a list
       pointing to the new node, to let the garbage collection know it's in use. */
      lists[index][0] = oldchain;
      lists[index][1] = newchain;

      size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;

      if (lastcount < numsymbols && sum > leaves[lastcount].weight) {
        /* New leaf inserted in list, so count is incremented. */
        InitNode(leaves[lastcount].weight, lastcount + 1, oldchain->tail, newchain);
      } else {
        InitNode(sum, lastcount, lists[index - 1][1], newchain);
        /* Two lookahead chains of previous list used up, create new ones. */

        if (unlikely(index == 1)){
          if(lists[0][1]->count < numsymbols){
            int last2count = lists[0][1]->count;
            lists[0][0] = lists[0][1];
            lists[0][1] = pool++;
            InitNode(leaves[last2count].weight, last2count + 1, 0, lists[0][1]);
            last2count++;
            if(last2count < numsymbols){
              lists[0][0] = lists[0][1];
              lists[0][1] = pool++;
              InitNode(leaves[last2count].weight, last2count + 1, 0, lists[0][1]);
            }
          }
        }
        else{
          stackspace[stackpos++] = index - 1;
          stackspace[stackpos++] = index - 1;
        }
      }
      if(!stackpos--){
        break;
      }
    }
  }
  BoundaryPMfinal(lists, leaves, numsymbols, pool, maxbits - 1);

  ExtractBitLengths(lists[maxbits - 1][1], leaves, bitlengths);
}
<commit_msg>Fix rare crash<commit_after>/*
Copyright 2011 Google Inc. 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 obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Author: lode.vandevenne@gmail.com (Lode Vandevenne)
Author: jyrki.alakuijala@gmail.com (Jyrki Alakuijala)
*/

/*
Bounded package merge algorithm, based on the paper
"A Fast and Space-Economical Algorithm for Length-Limited Coding
Jyrki Katajainen, Alistair Moffat, Andrew Turpin".
*/

/*Modified by Felix Hanau*/

#include "katajainen.h"
#include "util.h"

#include <stdlib.h>
#include <assert.h>
#include <algorithm>

/*
Nodes forming chains. Also used to represent leaves.
*/
typedef struct Node
{
  size_t weight;  /* Total weight (symbol count) of this chain. */
  Node* tail;  /* Previous node(s) of this chain, or 0 if none. */
  int count;  /* Leaf symbol index, or number of leaves before this chain. */
}
#if defined(__GNUC__) && (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64))
__attribute__((packed)) Node;
#else
Node;
#endif

/*
Initializes a chain node with the given values and marks it as in use.
*/
static void InitNode(size_t weight, int count, Node* tail, Node* node) {
  node->weight = weight;
  node->count = count;
  node->tail = tail;
}

static void BoundaryPMfinal(Node* (*lists)[2],
                            Node* leaves, int numsymbols, Node* pool, int index) {
  int lastcount = lists[index][1]->count;  /* Count of last chain of list. */

  size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;

  if (lastcount < numsymbols && sum > leaves[lastcount].weight) {

    Node* oldchain = lists[index][1]->tail;

    lists[index][1] = pool;
    pool->count = lastcount + 1;
    pool->tail = oldchain;

  }
  else{
    lists[index][1]->tail = lists[index - 1][1];
  }
}

/*
Initializes each list with as lookahead chains the two leaves with lowest
weights.
*/
static void InitLists(
    Node* pool, const Node* leaves, int maxbits, Node* (*lists)[2]) {
  Node* node0 = pool;
  Node* node1 = pool + 1;
  InitNode(leaves[0].weight, 1, 0, node0);
  InitNode(leaves[1].weight, 2, 0, node1);
  for (int i = 0; i < maxbits; i++) {
    lists[i][0] = node0;
    lists[i][1] = node1;
  }
}

/*
Converts result of boundary package-merge to the bitlengths. The result in the
last chain of the last list contains the amount of active leaves in each list.
chain: Chain to extract the bit length from (last chain from last list).
*/
static void ExtractBitLengths(Node* chain, Node* leaves, unsigned* bitlengths) {
  //Messy, but fast
  int counts[16] = {0};
  unsigned end = 16;
  for (Node* node = chain; node; node = node->tail) {
    end--;
    counts[end] = node->count;
  }

  unsigned ptr = 15;
  unsigned value = 1;
  unsigned val = counts[15];
  while (ptr >= end) {

    for (; val > counts[ptr - 1]; val--) {
      bitlengths[leaves[val - 1].count] = value;
    }
    ptr--;
    value++;
  }
}

void ZopfliLengthLimitedCodeLengths(const size_t* frequencies, int n, int maxbits, unsigned* bitlengths) {
  int i;
  int numsymbols = 0;  /* Amount of symbols with frequency > 0. */

  /* Array of lists of chains. Each list requires only two lookahead chains at
  a time, so each list is a array of two Node*'s. */

  /* One leaf per symbol. Only numsymbols leaves will be used. */
  Node leaves[288];

  /* Initialize all bitlengths at 0. */
  memset(bitlengths, 0, n * sizeof(unsigned));

  /* Count used symbols and place them in the leaves. */
  for (i = 0; i < n; i++) {
    if (frequencies[i]) {
      leaves[numsymbols].weight = frequencies[i];
      leaves[numsymbols].count = i;  /* Index of symbol this leaf represents. */
      numsymbols++;
    }
  }

  /* Check special cases and error conditions. */
  assert((1 << maxbits) >= numsymbols); /* Error, too few maxbits to represent symbols. */
  if (numsymbols == 0) {
    return;  /* No symbols at all. OK. */
  }
  if (numsymbols == 1) {
    bitlengths[leaves[0].count] = 1;
    return;  /* Only one symbol, give it bitlength 1, not 0. OK. */
  }
  if (numsymbols == 2){
    bitlengths[leaves[0].count]++;
    bitlengths[leaves[1].count]++;
    return;
  }

  struct {
    bool operator()(const Node a, const Node b) {
      return (a.weight < b.weight);
    }
  } cmp;

  /* Sort the leaves from lightest to heaviest. */
  for (i = 0; i < numsymbols; i++) {
    leaves[i].weight = (leaves[i].weight << 9) | leaves[i].count;
  }
  std::sort(leaves, leaves + numsymbols, cmp);

  for (i = 0; i < numsymbols; i++) {
    leaves[i].weight >>= 9;
  }

  if (numsymbols - 1 < maxbits) {
    maxbits = numsymbols - 1;
  }

  /* Initialize node memory pool. */
  Node* pool;
  Node stack[8580]; //maxbits(<=15) * 2 * numsymbols(<=286), the theoretical maximum. This needs about 170kb of memory, but is much faster than a node pool using garbage collection.
  pool = stack;

  Node list[15][2];
  Node* (* lists)[2]  = ( Node* (*)[2])list;
  InitLists(pool, leaves, maxbits, lists);
  pool += 2;

  /* In the last list, 2 * numsymbols - 2 active chains need to be created. Two
  are already created in the initialization. Each BoundaryPM run creates one. */
  int numBoundaryPMRuns = 2 * numsymbols - 4;
  unsigned char stackspace[16];

  for (i = 0; i < numBoundaryPMRuns - 1; i++) {
    unsigned stackpos = 0;
    stackspace[stackpos] = maxbits - 1;

    for(;;){
      unsigned char index = stackspace[stackpos];

      int lastcount = lists[index][1]->count;  /* Count of last chain of list. */

      Node* newchain = pool++;
      Node* oldchain = lists[index][1];

      /* These are set up before the recursive calls below, so that there is a list
       pointing to the new node, to let the garbage collection know it's in use. */
      lists[index][0] = oldchain;
      lists[index][1] = newchain;

      size_t sum = lists[index - 1][0]->weight + lists[index - 1][1]->weight;

      if (lastcount < numsymbols && sum > leaves[lastcount].weight) {
        /* New leaf inserted in list, so count is incremented. */
        InitNode(leaves[lastcount].weight, lastcount + 1, oldchain->tail, newchain);
      } else {
        InitNode(sum, lastcount, lists[index - 1][1], newchain);
        /* Two lookahead chains of previous list used up, create new ones. */

        if (unlikely(index == 1)){
          if(lists[0][1]->count < numsymbols){
            int last2count = lists[0][1]->count;
            lists[0][0] = lists[0][1];
            lists[0][1] = pool++;
            InitNode(leaves[last2count].weight, last2count + 1, 0, lists[0][1]);
            last2count++;
            if(last2count < numsymbols){
              lists[0][0] = lists[0][1];
              lists[0][1] = pool++;
              InitNode(leaves[last2count].weight, last2count + 1, 0, lists[0][1]);
            }
          }
        }
        else{
          stackspace[stackpos++] = index - 1;
          stackspace[stackpos++] = index - 1;
        }
      }
      if(!stackpos--){
        break;
      }
    }
  }
  BoundaryPMfinal(lists, leaves, numsymbols, pool, maxbits - 1);

  ExtractBitLengths(lists[maxbits - 1][1], leaves, bitlengths);
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_PROPERTIES_UTIL_HPP
#define MAPNIK_PROPERTIES_UTIL_HPP

#include <mapnik/symbolizer.hpp>
#include <mapnik/xml_node.hpp>
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/config_error.hpp>
#include <boost/optional.hpp>
#include <string>

namespace mapnik { namespace detail {

// text_layout_properties

template <typename T0, typename T1>
struct set_property_from_xml_impl
{
    using target_type = T0;
    static void apply(T1 & val, char const* name, xml_node const& node)
    {
        try
        {
            boost::optional<target_type> val_ = node.get_opt_attr<target_type>(name);
            if (val_) val = *val_;
        }
        catch (config_error const& ex)
        {
            boost::optional<expression_ptr> val_ = node.get_opt_attr<expression_ptr>(name);
            if (val_) val = *val_;
            else
            {
                ex.append_context(std::string("set_property_from_xml'"+ std::string(name) + "'"), node);
            }
        }
    }
};

template <typename T>
struct set_property_from_xml_impl<text_transform_e, T>
{
    using target_type = T;
    static void apply(T & val, char const* name, xml_node const& node)
    {
        try
        {
            boost::optional<std::string> enum_str = node.get_opt_attr<std::string>(name);
            if (enum_str)
            {
                text_transform_e e;
                e.from_string(*enum_str);
                val = enumeration_wrapper(e);
            }
        }
        catch (...)//config_error const& ex)
        {
            boost::optional<expression_ptr> expr = node.get_opt_attr<expression_ptr>(name);
            if (expr) val = *expr;
            else
            {
                throw config_error(std::string("set_property_from_xml'"+ std::string(name)));
                //ex.append_context(std::string("set_property_from_xml'"+ std::string(name) + "'"), node);
            }
        }
    }
};

} // namespace detail

template <typename T0, typename T1>
void set_property_from_xml(T1 & val, char const* name, xml_node const& node)
{
    detail::set_property_from_xml_impl<T0,T1>::apply(val, name, node);
}

void serialize_property(std::string const& name, symbolizer_base::value_type const& val, boost::property_tree::ptree & node);

} // namespace mapnik

#endif // MAPNIK_PROPERTIES_UTIL_HPP
<commit_msg>generic set_property_from_xml implementation<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_PROPERTIES_UTIL_HPP
#define MAPNIK_PROPERTIES_UTIL_HPP

#include <mapnik/symbolizer.hpp>
#include <mapnik/xml_node.hpp>
#include <mapnik/ptree_helpers.hpp>
#include <mapnik/config_error.hpp>
#include <boost/optional.hpp>
#include <string>

namespace mapnik { namespace detail {

template <typename T, class Enable = void>
struct is_mapnik_enumeration
{
    static constexpr bool value = false;
};

template <typename T>
struct is_mapnik_enumeration<T, typename std::enable_if<std::is_enum<typename T::native_type>::value>::type>
{
    static constexpr bool value = true;
};

template <typename T0, typename T1, bool is_mapnik_enumeration = false>
struct set_property_from_xml_impl
{
    using target_type = T0;
    static void apply(T1 & val, char const* name, xml_node const& node)
    {
        try
        {
            boost::optional<target_type> val_ = node.get_opt_attr<target_type>(name);
            if (val_) val = *val_;
        }
        catch (config_error const& ex)
        {
            boost::optional<expression_ptr> val_ = node.get_opt_attr<expression_ptr>(name);
            if (val_) val = *val_;
            else
            {
                ex.append_context(std::string("set_property_from_xml'"+ std::string(name) + "'"), node);
            }
        }
    }
};

template <typename T0, typename T1>
struct set_property_from_xml_impl<T0, T1, true>
{
    using target_enum_type = T0;
    static void apply(T1 & val, char const* name, xml_node const& node)
    {
        try
        {
            boost::optional<std::string> enum_str = node.get_opt_attr<std::string>(name);
            if (enum_str)
            {
                target_enum_type e;
                e.from_string(*enum_str);
                val = enumeration_wrapper(e);
            }
        }
        catch (...)
        {
            boost::optional<expression_ptr> expr = node.get_opt_attr<expression_ptr>(name);
            if (expr) val = *expr;
            else
            {
                throw config_error(std::string("set_property_from_xml'"+ std::string(name)));
            }
        }
    }
};

} // namespace detail

template <typename T0, typename T1>
void set_property_from_xml(T1 & val, char const* name, xml_node const& node)
{
    detail::set_property_from_xml_impl<T0, T1, detail::is_mapnik_enumeration<T0>::value>::apply(val, name, node);
}

void serialize_property(std::string const& name, symbolizer_base::value_type const& val, boost::property_tree::ptree & node);

} // namespace mapnik

#endif // MAPNIK_PROPERTIES_UTIL_HPP
<|endoftext|>