<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
#define _POSIX_SOURCE

#include "condor_common.h"
#include "condor_constants.h"
#include "condor_io.h"
#include "condor_debug.h"

unsigned long num_created = 0;
unsigned long num_deleted = 0;

void
sanity_check()
{
	dprintf(D_ALWAYS, "IO: Buffer management:\n");
	dprintf(D_ALWAYS, "IO:     created: %d\n", num_created);
	dprintf(D_ALWAYS, "IO:     deleted: %d\n\n", num_deleted);
}

Buf::Buf(
	int	sz
	)
{
	_dta = new char[sz];
	_dta_maxsz = sz;
	_dta_sz = 0;
	_dta_pt = 0;
	_next = NULL;
	num_created++;
}

Buf::~Buf()
{
	if (_dta) delete [] _dta;
	num_deleted++;
}

int Buf::write(
	SOCKET	sockd,
	int		sz,
	int		timeout
	)
{
	int	nw;
	int nwo;
	unsigned int start_time, curr_time;

	if (sz < 0 || sz > num_untouched()) sz = num_untouched();

	if ( timeout > 0 ) {
		start_time = time(NULL);
		curr_time = start_time;
	}

	for(nw=0;nw < sz;) {
		if (timeout > 0) {
			struct timeval	timer;
			fd_set			writefds;
			int				nfds=0, nfound;

			if ( curr_time == 0 )
				curr_time = time(NULL);
			if ( start_time + timeout > curr_time ) {
				timer.tv_sec = (start_time + timeout) - curr_time;
			} else {
				dprintf(D_ALWAYS,"timeout reading in Buf::write()\n");
				return -1;
			}
			curr_time = 0;	// so we call time() next time around
			timer.tv_usec = 0;
	#if !defined(WIN32) // nfds is ignored on WIN32
			nfds = sockd + 1;
	#endif
			FD_ZERO( &writefds );
			FD_SET( sockd, &writefds );

			nfound = select( nfds, 0, &writefds, 0, &timer );

			switch(nfound) {
			case 0:
				dprintf(D_ALWAYS,"select timed out in Buf::write()\n");
				return -1;
				break;
			case 1:
				break;
			default:
				dprintf( D_ALWAYS, "select returns %d, send failed\n",
					nfound );
				return -1;
				break;
			}
		}

		nwo = send(sockd, &_dta[num_touched()+nw], sz-nw, 0);
		if (nwo <= 0) {
			dprintf(D_FULLDEBUG,"Buf:Write send failed, sock=%X, err=%d, len=%d\n",
				sockd,WSAGetLastError(),sz-nw);
			return -1;
		}

		nw += nwo;
	}

	_dta_pt += nw;
	return nw;
}

int Buf::flush(
	SOCKET	sockd,
	void	*hdr,
	int		sz,
	int		timeout
	)
{
/* DEBUG SESSION
	int		dbg_fd;
*/

	if (sz > max_size()) return -1;
	if (hdr && sz > 0){
		memcpy(_dta, hdr, sz);
	}

	rewind();

/* DEBUG SESSION
	if ((dbg_fd = open("trace.snd", O_WRONLY|O_APPEND|O_CREAT, 0700)) < 0){
		dprintf(D_ALWAYS, "IO: Error opening trace file\n");
		exit(1);
	}
	if (write(dbg_fd, _dta, _dta_maxsz) != _dta_maxsz){
		dprintf(D_ALWAYS, "IO: ERROR LOGGING\n");
		return FALSE;
	}
	::close(dbg_fd);
*/

	sz = write(sockd, -1, timeout);
	reset();

	return sz;
}

int Buf::read(
	SOCKET	sockd,
	int		sz,
	int		timeout
	)
{
	int	nr;
	int nro;
	unsigned int start_time, curr_time;

	if (sz < 0 || sz > num_free()){
		dprintf(D_ALWAYS, "IO: Buffer too small\n");
		return -1;
		/* sz = num_free(); */
	}

	if ( timeout > 0 ) {
		start_time = time(NULL);
		curr_time = start_time;
	}

	for(nr=0;nr <sz;){

		if (timeout > 0) {
			struct timeval	timer;
			fd_set			readfds;
			int				nfds=0, nfound;

			if ( curr_time == 0 )
				curr_time = time(NULL);
			if ( start_time + timeout > curr_time ) {
				timer.tv_sec = (start_time + timeout) - curr_time;
			} else {
				dprintf(D_ALWAYS,"timeout reading in Buf::read()\n");
				return -1;
			}
			curr_time = 0;	// so we call time() next time around
			timer.tv_usec = 0;
#if !defined(WIN32) // nfds is ignored on WIN32
			nfds = sockd + 1;
#endif
			FD_ZERO( &readfds );
			FD_SET( sockd, &readfds );

			nfound = select( nfds, &readfds, 0, 0, &timer );

			switch(nfound) {
			case 0:
				dprintf( D_ALWAYS, "select timed out in Buf::read()\n" );
				return -1;
			case 1:
				break;
			default:
				dprintf( D_ALWAYS, "select returns %d, recv failed\n",
					nfound );
				return -1;
			}
		}

		nro = recv(sockd, &_dta[num_used()+nr], sz-nr, 0);

		if (nro <= 0) {
			dprintf( D_ALWAYS, "recv returned %d, errno = %d\n",
					 nro, errno );
			return -1;
		}

		nr += nro;
	}

	_dta_sz += nr;

/* DEBUG SESSION
	if ((dbg_fd = open("trace.rcv", O_WRONLY|O_APPEND|O_CREAT, 0700)) < 0){
		dprintf(D_ALWAYS, "IO: Error opening trace file\n");
		exit(1);
	}
	if (write(dbg_fd, _dta, _dta_maxsz) != _dta_maxsz){
		dprintf(D_ALWAYS, "IO: ERROR LOGGING\n");
		return FALSE;
	}
	::close(dbg_fd);
*/

	return nr;
}

int Buf::put_max(
	const void	*dta,
	int			sz
	)
{
	if (sz > num_free()) sz = num_free();

	memcpy(&_dta[num_used()], dta, sz);

	_dta_sz += sz;
	return sz;
}

int Buf::get_max(
	void		*dta,
	int			sz
	)
{
	if (sz > num_untouched()) sz = num_untouched();

	memcpy(dta, &_dta[num_touched()], sz);

	_dta_pt += sz;
	return sz;
}

int Buf::find(
	char	delim
	)
{
	char	*tmp;

	if (!(tmp = (char *)memchr(&_dta[num_touched()], delim, num_untouched()))){
		return -1;
	}

	return (tmp - &_dta[num_touched()]);
}

int Buf::peek(
	char		&c
	)
{
	if (empty() || consumed()) return FALSE;

	c = _dta[num_touched()];
	return TRUE;
}

int Buf::seek(
	int		pos
	)
{
	int	tmp;

	tmp = _dta_pt;
	_dta_pt = (pos < 0) ? 0 : ((pos < _dta_maxsz) ? pos : _dta_maxsz-1);
	if (_dta_pt > _dta_sz) _dta_sz = _dta_pt;
	return tmp;
}

void ChainBuf::reset()
{
	Buf	*trav;
	Buf	*trav_n;

	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }

	for(trav=_head; trav; trav=trav_n){
		trav_n = trav->next();
		delete trav;
	}

	_head = _tail = _curr = (Buf *)0;
}

int dbg_count = 0;

int ChainBuf::get(
	void	*dta,
	int		sz
	)
{
	int		last_incr;
	int		nr;

	if (dbg_count++ > 307){
		dbg_count--;
	}

	for(nr=0; _curr; _curr=_curr->next()){
		last_incr = _curr->get_max(&((char *)dta)[nr], sz-nr);
		nr += last_incr;
		if (nr == sz) break;
	}

	return nr;
}

int ChainBuf::put(
	Buf		*dta
	)
{
	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }

	if (!_tail){
		_head = _tail = _curr = dta;
		dta->set_next((Buf *)0);
	}
	else{
		_tail->set_next(dta);
		_tail = dta;
		_tail->set_next((Buf *)0);
	}

	return TRUE;
}

int ChainBuf::get_tmp(
	void	*&ptr,
	char	delim
	)
{
	int	nr;
	int	tr;
	Buf	*trav;

	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }

	if (!_curr) return -1;

	/* case 1: in one buffer */
	if ((tr = _curr->find(delim)) >= 0){
		ptr = _curr->get_ptr();
		nr = _curr->seek(0);
		_curr->seek(nr+tr+1);
		return tr+1;
	}

	/* case 2: string is in >1 buffers. */

	nr = _curr->num_untouched();
	if (!_curr->next()) return -1;

	for(trav = _curr->next(); trav; trav = trav->next()){
		if ((tr = trav->find(delim)) < 0){
			nr += trav->num_untouched();
		}
		else{
			nr += tr;
			if (!(_tmp = new char[nr+1])) return -1;
			get(_tmp, nr+1);
			ptr = _tmp;
			return nr+1;
		}
	}

	return -1;
}

int ChainBuf::peek(
	char	&c
	)
{
	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }
	if (!_curr) return FALSE;

	if (!_curr->peek(c)){
		if (!(_curr = _curr->next())) return FALSE;
		return _curr->peek(c);
	}

	return TRUE;
}

<commit_msg>fixed last checkin (broke build on Unix)<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
 * CONDOR Copyright Notice
 *
 * See LICENSE.TXT for additional notices and disclaimers.
 *
 * Copyright (c)1990-1998 CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, Madison, WI.  All Rights Reserved.
 * No use of the CONDOR Software Program Source Code is authorized
 * without the express consent of the CONDOR Team.  For more information
 * contact: CONDOR Team, Attention: Professor Miron Livny,
 * 7367 Computer Sciences, 1210 W. Dayton St., Madison, WI 53706-1685,
 * (608) 262-0856 or miron@cs.wisc.edu.
 *
 * U.S. Government Rights Restrictions: Use, duplication, or disclosure
 * by the U.S. Government is subject to restrictions as set forth in
 * subparagraph (c)(1)(ii) of The Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 or subparagraphs (c)(1) and
 * (2) of Commercial Computer Software-Restricted Rights at 48 CFR
 * 52.227-19, as applicable, CONDOR Team, Attention: Professor Miron
 * Livny, 7367 Computer Sciences, 1210 W. Dayton St., Madison,
 * WI 53706-1685, (608) 262-0856 or miron@cs.wisc.edu.
****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
#define _POSIX_SOURCE

#include "condor_common.h"
#include "condor_constants.h"
#include "condor_io.h"
#include "condor_debug.h"

unsigned long num_created = 0;
unsigned long num_deleted = 0;

void
sanity_check()
{
	dprintf(D_ALWAYS, "IO: Buffer management:\n");
	dprintf(D_ALWAYS, "IO:     created: %d\n", num_created);
	dprintf(D_ALWAYS, "IO:     deleted: %d\n\n", num_deleted);
}

Buf::Buf(
	int	sz
	)
{
	_dta = new char[sz];
	_dta_maxsz = sz;
	_dta_sz = 0;
	_dta_pt = 0;
	_next = NULL;
	num_created++;
}

Buf::~Buf()
{
	if (_dta) delete [] _dta;
	num_deleted++;
}

int Buf::write(
	SOCKET	sockd,
	int		sz,
	int		timeout
	)
{
	int	nw;
	int nwo;
	unsigned int start_time, curr_time;

	if (sz < 0 || sz > num_untouched()) sz = num_untouched();

	if ( timeout > 0 ) {
		start_time = time(NULL);
		curr_time = start_time;
	}

	for(nw=0;nw < sz;) {
		if (timeout > 0) {
			struct timeval	timer;
			fd_set			writefds;
			int				nfds=0, nfound;

			if ( curr_time == 0 )
				curr_time = time(NULL);
			if ( start_time + timeout > curr_time ) {
				timer.tv_sec = (start_time + timeout) - curr_time;
			} else {
				dprintf(D_ALWAYS,"timeout reading in Buf::write()\n");
				return -1;
			}
			curr_time = 0;	// so we call time() next time around
			timer.tv_usec = 0;
	#if !defined(WIN32) // nfds is ignored on WIN32
			nfds = sockd + 1;
	#endif
			FD_ZERO( &writefds );
			FD_SET( sockd, &writefds );

			nfound = select( nfds, 0, &writefds, 0, &timer );

			switch(nfound) {
			case 0:
				dprintf(D_ALWAYS,"select timed out in Buf::write()\n");
				return -1;
				break;
			case 1:
				break;
			default:
				dprintf( D_ALWAYS, "select returns %d, send failed\n",
					nfound );
				return -1;
				break;
			}
		}

		nwo = send(sockd, &_dta[num_touched()+nw], sz-nw, 0);
		if (nwo <= 0) {
			dprintf(D_FULLDEBUG,"Buf:Write send failed, sock=%X, err=%d, len=%d\n",
				sockd,
#ifdef WIN32
				WSAGetLastError(),
#else
				errno,
#endif
				sz-nw);
			return -1;
		}

		nw += nwo;
	}

	_dta_pt += nw;
	return nw;
}

int Buf::flush(
	SOCKET	sockd,
	void	*hdr,
	int		sz,
	int		timeout
	)
{
/* DEBUG SESSION
	int		dbg_fd;
*/

	if (sz > max_size()) return -1;
	if (hdr && sz > 0){
		memcpy(_dta, hdr, sz);
	}

	rewind();

/* DEBUG SESSION
	if ((dbg_fd = open("trace.snd", O_WRONLY|O_APPEND|O_CREAT, 0700)) < 0){
		dprintf(D_ALWAYS, "IO: Error opening trace file\n");
		exit(1);
	}
	if (write(dbg_fd, _dta, _dta_maxsz) != _dta_maxsz){
		dprintf(D_ALWAYS, "IO: ERROR LOGGING\n");
		return FALSE;
	}
	::close(dbg_fd);
*/

	sz = write(sockd, -1, timeout);
	reset();

	return sz;
}

int Buf::read(
	SOCKET	sockd,
	int		sz,
	int		timeout
	)
{
	int	nr;
	int nro;
	unsigned int start_time, curr_time;

	if (sz < 0 || sz > num_free()){
		dprintf(D_ALWAYS, "IO: Buffer too small\n");
		return -1;
		/* sz = num_free(); */
	}

	if ( timeout > 0 ) {
		start_time = time(NULL);
		curr_time = start_time;
	}

	for(nr=0;nr <sz;){

		if (timeout > 0) {
			struct timeval	timer;
			fd_set			readfds;
			int				nfds=0, nfound;

			if ( curr_time == 0 )
				curr_time = time(NULL);
			if ( start_time + timeout > curr_time ) {
				timer.tv_sec = (start_time + timeout) - curr_time;
			} else {
				dprintf(D_ALWAYS,"timeout reading in Buf::read()\n");
				return -1;
			}
			curr_time = 0;	// so we call time() next time around
			timer.tv_usec = 0;
#if !defined(WIN32) // nfds is ignored on WIN32
			nfds = sockd + 1;
#endif
			FD_ZERO( &readfds );
			FD_SET( sockd, &readfds );

			nfound = select( nfds, &readfds, 0, 0, &timer );

			switch(nfound) {
			case 0:
				dprintf( D_ALWAYS, "select timed out in Buf::read()\n" );
				return -1;
			case 1:
				break;
			default:
				dprintf( D_ALWAYS, "select returns %d, recv failed\n",
					nfound );
				return -1;
			}
		}

		nro = recv(sockd, &_dta[num_used()+nr], sz-nr, 0);

		if (nro <= 0) {
			dprintf( D_ALWAYS, "recv returned %d, errno = %d\n",
					 nro, errno );
			return -1;
		}

		nr += nro;
	}

	_dta_sz += nr;

/* DEBUG SESSION
	if ((dbg_fd = open("trace.rcv", O_WRONLY|O_APPEND|O_CREAT, 0700)) < 0){
		dprintf(D_ALWAYS, "IO: Error opening trace file\n");
		exit(1);
	}
	if (write(dbg_fd, _dta, _dta_maxsz) != _dta_maxsz){
		dprintf(D_ALWAYS, "IO: ERROR LOGGING\n");
		return FALSE;
	}
	::close(dbg_fd);
*/

	return nr;
}

int Buf::put_max(
	const void	*dta,
	int			sz
	)
{
	if (sz > num_free()) sz = num_free();

	memcpy(&_dta[num_used()], dta, sz);

	_dta_sz += sz;
	return sz;
}

int Buf::get_max(
	void		*dta,
	int			sz
	)
{
	if (sz > num_untouched()) sz = num_untouched();

	memcpy(dta, &_dta[num_touched()], sz);

	_dta_pt += sz;
	return sz;
}

int Buf::find(
	char	delim
	)
{
	char	*tmp;

	if (!(tmp = (char *)memchr(&_dta[num_touched()], delim, num_untouched()))){
		return -1;
	}

	return (tmp - &_dta[num_touched()]);
}

int Buf::peek(
	char		&c
	)
{
	if (empty() || consumed()) return FALSE;

	c = _dta[num_touched()];
	return TRUE;
}

int Buf::seek(
	int		pos
	)
{
	int	tmp;

	tmp = _dta_pt;
	_dta_pt = (pos < 0) ? 0 : ((pos < _dta_maxsz) ? pos : _dta_maxsz-1);
	if (_dta_pt > _dta_sz) _dta_sz = _dta_pt;
	return tmp;
}

void ChainBuf::reset()
{
	Buf	*trav;
	Buf	*trav_n;

	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }

	for(trav=_head; trav; trav=trav_n){
		trav_n = trav->next();
		delete trav;
	}

	_head = _tail = _curr = (Buf *)0;
}

int dbg_count = 0;

int ChainBuf::get(
	void	*dta,
	int		sz
	)
{
	int		last_incr;
	int		nr;

	if (dbg_count++ > 307){
		dbg_count--;
	}

	for(nr=0; _curr; _curr=_curr->next()){
		last_incr = _curr->get_max(&((char *)dta)[nr], sz-nr);
		nr += last_incr;
		if (nr == sz) break;
	}

	return nr;
}

int ChainBuf::put(
	Buf		*dta
	)
{
	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }

	if (!_tail){
		_head = _tail = _curr = dta;
		dta->set_next((Buf *)0);
	}
	else{
		_tail->set_next(dta);
		_tail = dta;
		_tail->set_next((Buf *)0);
	}

	return TRUE;
}

int ChainBuf::get_tmp(
	void	*&ptr,
	char	delim
	)
{
	int	nr;
	int	tr;
	Buf	*trav;

	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }

	if (!_curr) return -1;

	/* case 1: in one buffer */
	if ((tr = _curr->find(delim)) >= 0){
		ptr = _curr->get_ptr();
		nr = _curr->seek(0);
		_curr->seek(nr+tr+1);
		return tr+1;
	}

	/* case 2: string is in >1 buffers. */

	nr = _curr->num_untouched();
	if (!_curr->next()) return -1;

	for(trav = _curr->next(); trav; trav = trav->next()){
		if ((tr = trav->find(delim)) < 0){
			nr += trav->num_untouched();
		}
		else{
			nr += tr;
			if (!(_tmp = new char[nr+1])) return -1;
			get(_tmp, nr+1);
			ptr = _tmp;
			return nr+1;
		}
	}

	return -1;
}

int ChainBuf::peek(
	char	&c
	)
{
	if (_tmp) { delete [] _tmp; _tmp = (char *)0; }
	if (!_curr) return FALSE;

	if (!_curr->peek(c)){
		if (!(_curr = _curr->next())) return FALSE;
		return _curr->peek(c);
	}

	return TRUE;
}

<|endoftext|>


<commit_before>#include <iostream.h>
#include "condor_common.h"
#include "_condor_fix_resource.h"
#include "condor_config.h"
#include "condor_q.h"
#include "condor_attributes.h"
#include "files.h"

extern "C" int SetSyscalls(int val){return val;}
void short_print (int, int, const char*, int, int, int, int, int, const char *);
extern "C" void set_debug_flags( char * );
extern "C" char *get_schedd_addr(const char *);

static void short_header (void);
static void usage (char *);
static void displayJobShort (ClassAd *);
static void shorten (char *, int);

static int verbose = 0, summarize = 1;
static int malformed, unexpanded, running, idle;

extern	"C" BUCKET*		ConfigTab[];
extern "C" extern int Termlog;

int main (int argc, char **argv)
{
	CondorQ 		  Q;
	ClassAdList 	  jobs;
	ClassAd           *job;
	int               i;
	int               cluster, proc;
	char              constraint[1024];
	char              *host = 0;
	char*				scheddAddr;

	for (i = 1; i < argc; i++)
	{
		if (strcmp (argv[i], "-l") == 0)
		{
			verbose = 1;
			summarize = 0;
		}
		else
		if (strcmp (argv[i], "-D") == 0)
		{
			Termlog = 1;
			set_debug_flags( argv[++i] );
		}
		else
		if (strcmp (argv[i], "-h") == 0)
		{
			host = argv[++i];
		}
		else
		if (strcmp (argv[i], "-C") == 0)
		{
			Q.add (argv[++i]);
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2)
		{
			sprintf (constraint, "((%s == %d) && (%s == %d))",
									ATTR_CLUSTER_ID, cluster,
									ATTR_PROC_ID, proc);
			Q.add (constraint);
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d", &cluster) == 1)
		{
			sprintf (constraint, "(%s == %d)", ATTR_CLUSTER_ID, cluster);
			Q.add (constraint);
			summarize = 0;
		}
		else
		{
			usage (argv[0]);
			exit (1);
		}
	}

	config( 0 );

	// find ip port of schedd from collector
	if(!host)
	{
		host = new char[256];
		if(gethostname(host, 256) < 0)
		{
			printf("Can't find host\n");
			exit(1);
		}
	}
	if((scheddAddr = get_schedd_addr(host)) == NULL)
	{
		printf("Can't find schedd address on %s\n", host);
		exit(1);
	}

	// fetch queue from schedd
	if (Q.fetchQueueFromHost (jobs, scheddAddr) != Q_OK)
	{
		printf ("Error connecting to job queue\n");
		exit (1);
	}

	// initialize counters
	malformed = 0; idle = 0; running = 0; unexpanded = 0;

	if (verbose)
	{
		jobs.fPrintAttrListList (stdout);
	}
	else
	{
		short_header ();
		jobs.Open ();
		while (job = jobs.Next())
		{
			displayJobShort (job);
		}
		jobs.Close ();
	}

	if (summarize)
	{
		printf ("\n%d jobs; %d unexpanded, %d idle, %d running, %d malformed\n",
				unexpanded+idle+running+malformed, unexpanded, idle, running,
				malformed);
	}

	return 0;
}

static void
displayJobShort (ClassAd *ad)
{
	int cluster, proc, date, status, prio, image_size;
	float utime;
	char owner[64], cmd[2048], args[2048];

	if (!ad->EvalInteger (ATTR_CLUSTER_ID, NULL, cluster)		||
		!ad->EvalInteger (ATTR_PROC_ID, NULL, proc)				||
		!ad->EvalInteger (ATTR_Q_DATE, NULL, date)				||
		!ad->EvalFloat   (ATTR_JOB_REMOTE_USER_CPU, NULL, utime)	||
		!ad->EvalInteger (ATTR_JOB_STATUS, NULL, status)			||
		!ad->EvalInteger (ATTR_JOB_PRIO, NULL, prio)				||
		!ad->EvalInteger (ATTR_IMAGE_SIZE, NULL, image_size)		||
		!ad->EvalString  (ATTR_OWNER, NULL, owner)				||
		!ad->EvalString  (ATTR_JOB_CMD, NULL, cmd) )
	{
		printf (" --- ???? --- \n");
		return;
	}

	shorten (owner, 14);
	if (ad->EvalString ("Args", NULL, args)) strcat (cmd, args);
	shorten (cmd, 18);
	short_print (cluster, proc, owner, date, (int)utime, status, prio,
					image_size, cmd);

	switch (status)
	{
		case UNEXPANDED: unexpanded++; break;
		case IDLE:       idle++;       break;
		case RUNNING:    running++;    break;
	}
}

static void
short_header (void)
{
    printf( " %-7s %-14s %11s %12s %-2s %-3s %-4s %-18s\n",
        "ID",
        "OWNER",
        "SUBMITTED",
        "CPU_USAGE",
        "ST",
        "PRI",
        "SIZE",
        "CMD"
    );
}

static void
shorten (char *buff, int len)
{
	if ((unsigned int)strlen (buff) > (unsigned int)len) buff[len] = '\0';
}

static void
usage (char *myName)
{
	printf ("usage: %s [-h <host>] [-l] [<constraint> ...]\n", myName);
	printf ("\twhere <host> is one of:\n");
	printf ("\t\thostname\n\t\t<hostname:port>\n\t\t<xx.xx.xx.xx:port>\n");
	printf ("\tand a <constraint> is one of:\n");
	printf ("\t\tcluster\n\t\tcluster.proc\n\t\t-C <ClassAd expression>\n");
}
<commit_msg>need to sort the queue now, since the schedd keeps it in a hashtable<commit_after>#include <iostream.h>
#include "condor_common.h"
#include "_condor_fix_resource.h"
#include "condor_config.h"
#include "condor_q.h"
#include "condor_attributes.h"
#include "files.h"

extern "C" int SetSyscalls(int val){return val;}
void short_print (int, int, const char*, int, int, int, int, int, const char *);
extern "C" void set_debug_flags( char * );
extern "C" char *get_schedd_addr(const char *);

static void short_header (void);
static void usage (char *);
static void displayJobShort (ClassAd *);
static void shorten (char *, int);

static int verbose = 0, summarize = 1;
static int malformed, unexpanded, running, idle;

extern	"C" BUCKET*		ConfigTab[];
extern "C" extern int Termlog;

int main (int argc, char **argv)
{
	CondorQ 		  Q;
	ClassAdList 	  jobs;
	ClassAd           *job;
	int               i;
	int               cluster, proc;
	char              constraint[1024];
	char              *host = 0;
	char*				scheddAddr;

	for (i = 1; i < argc; i++)
	{
		if (strcmp (argv[i], "-l") == 0)
		{
			verbose = 1;
			summarize = 0;
		}
		else
		if (strcmp (argv[i], "-D") == 0)
		{
			Termlog = 1;
			set_debug_flags( argv[++i] );
		}
		else
		if (strcmp (argv[i], "-h") == 0)
		{
			host = argv[++i];
		}
		else
		if (strcmp (argv[i], "-C") == 0)
		{
			Q.add (argv[++i]);
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2)
		{
			sprintf (constraint, "((%s == %d) && (%s == %d))",
									ATTR_CLUSTER_ID, cluster,
									ATTR_PROC_ID, proc);
			Q.add (constraint);
			summarize = 0;
		}
		else
		if (sscanf (argv[i], "%d", &cluster) == 1)
		{
			sprintf (constraint, "(%s == %d)", ATTR_CLUSTER_ID, cluster);
			Q.add (constraint);
			summarize = 0;
		}
		else
		{
			usage (argv[0]);
			exit (1);
		}
	}

	config( 0 );

	// find ip port of schedd from collector
	if(!host)
	{
		host = new char[256];
		if(gethostname(host, 256) < 0)
		{
			printf("Can't find host\n");
			exit(1);
		}
	}
	if((scheddAddr = get_schedd_addr(host)) == NULL)
	{
		printf("Can't find schedd address on %s\n", host);
		exit(1);
	}

	// fetch queue from schedd
	if (Q.fetchQueueFromHost (jobs, scheddAddr) != Q_OK)
	{
		printf ("Error connecting to job queue\n");
		exit (1);
	}

	// sort queue by cluster.proc
	jobs.Sort((int(*)(AttrListAbstract *, AttrListAbstract *, void *))JobSort);

	// initialize counters
	malformed = 0; idle = 0; running = 0; unexpanded = 0;

	if (verbose)
	{
		jobs.fPrintAttrListList (stdout);
	}
	else
	{
		short_header ();
		jobs.Open ();
		while (job = jobs.Next())
		{
			displayJobShort (job);
		}
		jobs.Close ();
	}

	if (summarize)
	{
		printf ("\n%d jobs; %d unexpanded, %d idle, %d running, %d malformed\n",
				unexpanded+idle+running+malformed, unexpanded, idle, running,
				malformed);
	}

	return 0;
}

static void
displayJobShort (ClassAd *ad)
{
	int cluster, proc, date, status, prio, image_size;
	float utime;
	char owner[64], cmd[2048], args[2048];

	if (!ad->EvalInteger (ATTR_CLUSTER_ID, NULL, cluster)		||
		!ad->EvalInteger (ATTR_PROC_ID, NULL, proc)				||
		!ad->EvalInteger (ATTR_Q_DATE, NULL, date)				||
		!ad->EvalFloat   (ATTR_JOB_REMOTE_USER_CPU, NULL, utime)	||
		!ad->EvalInteger (ATTR_JOB_STATUS, NULL, status)			||
		!ad->EvalInteger (ATTR_JOB_PRIO, NULL, prio)				||
		!ad->EvalInteger (ATTR_IMAGE_SIZE, NULL, image_size)		||
		!ad->EvalString  (ATTR_OWNER, NULL, owner)				||
		!ad->EvalString  (ATTR_JOB_CMD, NULL, cmd) )
	{
		printf (" --- ???? --- \n");
		return;
	}

	shorten (owner, 14);
	if (ad->EvalString ("Args", NULL, args)) strcat (cmd, args);
	shorten (cmd, 18);
	short_print (cluster, proc, owner, date, (int)utime, status, prio,
					image_size, cmd);

	switch (status)
	{
		case UNEXPANDED: unexpanded++; break;
		case IDLE:       idle++;       break;
		case RUNNING:    running++;    break;
	}
}

static void
short_header (void)
{
    printf( " %-7s %-14s %11s %12s %-2s %-3s %-4s %-18s\n",
        "ID",
        "OWNER",
        "SUBMITTED",
        "CPU_USAGE",
        "ST",
        "PRI",
        "SIZE",
        "CMD"
    );
}

static void
shorten (char *buff, int len)
{
	if ((unsigned int)strlen (buff) > (unsigned int)len) buff[len] = '\0';
}

static void
usage (char *myName)
{
	printf ("usage: %s [-h <host>] [-l] [<constraint> ...]\n", myName);
	printf ("\twhere <host> is one of:\n");
	printf ("\t\thostname\n\t\t<hostname:port>\n\t\t<xx.xx.xx.xx:port>\n");
	printf ("\tand a <constraint> is one of:\n");
	printf ("\t\tcluster\n\t\tcluster.proc\n\t\t-C <ClassAd expression>\n");
}
<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkImageToIGTLMessageFilter.h"
#include "mitkImageReadAccessor.h"
#include "itkByteSwapper.h"
#include "igtlImageMessage.h"

mitk::ImageToIGTLMessageFilter::ImageToIGTLMessageFilter()
{
  mitk::IGTLMessage::Pointer output = mitk::IGTLMessage::New();
  this->SetNumberOfRequiredOutputs(1);
  this->SetNthOutput(0, output.GetPointer());
  this->SetNumberOfRequiredInputs(1);
}

void mitk::ImageToIGTLMessageFilter::GenerateData()
{
  // MITK_INFO << "ImageToIGTLMessageFilter.GenerateData()";
  for (unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); ++i)
  {
    mitk::IGTLMessage* output = this->GetOutput(i);
    assert(output);

    const mitk::Image* img = this->GetInput(i);

    int dims = img->GetDimension();
    int chn = img->GetNumberOfChannels();

    if (dims < 1)
    {
      MITK_ERROR << "Can not handle dimensionless images";
    }
    if (dims > 3)
    {
      MITK_ERROR << "Can not handle more than three dimensions";
      continue;
    }

    if (chn != 1)
    {
      MITK_ERROR << "Can not handle anything but one channel. Image contained " << chn;
      continue;
    }

    igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New();

    // TODO: Which kind of coordinate system does MITK really use?
    imgMsg->SetCoordinateSystem(igtl::ImageMessage::COORDINATE_RAS);

    // We could do this based on the host endiannes, but that's weird.
    // We instead use little endian, as most modern systems are little endian,
    // so there will probably not be an endian swap involved.
    imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_LITTLE);

    // Set number of components.
    mitk::PixelType type = img->GetPixelType();
    imgMsg->SetNumComponents(type.GetNumberOfComponents());

    // Set scalar type.
    switch (type.GetComponentType())
    {
    case itk::ImageIOBase::CHAR:
      imgMsg->SetScalarTypeToInt8();
      break;
    case itk::ImageIOBase::UCHAR:
      imgMsg->SetScalarTypeToUint8();
      break;
    case itk::ImageIOBase::SHORT:
      imgMsg->SetScalarTypeToInt16();
      break;
    case itk::ImageIOBase::USHORT:
      imgMsg->SetScalarTypeToUint16();
      break;
    case itk::ImageIOBase::INT:
      imgMsg->SetScalarTypeToInt32();
      break;
    case itk::ImageIOBase::UINT:
      imgMsg->SetScalarTypeToUint32();
      break;
    case itk::ImageIOBase::LONG:
      // OIGTL doesn't formally support 64bit int scalars, but if they are
      // ever added,
      // they will have the identifier 8 assigned.
      imgMsg->SetScalarType(8);
      break;
    case itk::ImageIOBase::ULONG:
      // OIGTL doesn't formally support 64bit uint scalars, but if they are
      // ever added,
      // they will have the identifier 9 assigned.
      imgMsg->SetScalarType(9);
      break;
    case itk::ImageIOBase::FLOAT:
      // The igtl library has no method for this. Correct type is 10.
      imgMsg->SetScalarType(10);
      break;
    case itk::ImageIOBase::DOUBLE:
      // The igtl library has no method for this. Correct type is 11.
      imgMsg->SetScalarType(11);
      break;
    default:
      MITK_ERROR << "Can not handle pixel component type "
        << type.GetComponentType();
      return;
    }

    // Set transformation matrix.
    vtkMatrix4x4* matrix = img->GetGeometry()->GetVtkMatrix();

    float matF[4][4];
    for (size_t i = 0; i < 4; ++i)
    {
      for (size_t j = 0; j < 4; ++j)
      {
        matF[i][j] = matrix->GetElement(i, j);
      }
    }
    imgMsg->SetMatrix(matF);

    float spacing[3];
    auto spacingImg = img->GetGeometry()->GetSpacing();

    for (int i = 0; i < 3; ++i)
      spacing[i] = spacingImg[i];

    imgMsg->SetSpacing(spacing);

    // Set dimensions.
    int sizes[3];
    for (size_t j = 0; j < 3; ++j)
    {
      sizes[j] = img->GetDimension(j);
    }
    imgMsg->SetDimensions(sizes);

    // Allocate and copy data.
    imgMsg->AllocatePack();
    imgMsg->AllocateScalars();

    size_t num_pixel = sizes[0] * sizes[1] * sizes[2];
    void* out = imgMsg->GetScalarPointer();
    {
      // Scoped, so that readAccess will be released ASAP.
      mitk::ImageReadAccessor readAccess(img, img->GetChannelData(0));
      const void* in = readAccess.GetData();

      memcpy(out, in, num_pixel * type.GetSize());
    }

    // We want to byte swap to little endian. We would like to just
    // swap by number of bytes for each component, but itk::ByteSwapper
    // is templated over element type, not over element size. So we need to
    // switch on the size and use types of the same size.
    size_t num_scalars = num_pixel * type.GetNumberOfComponents();
    switch (type.GetComponentType())
    {
    case itk::ImageIOBase::CHAR:
    case itk::ImageIOBase::UCHAR:
      // No endian conversion necessary, because a char is exactly one byte!
      break;
    case itk::ImageIOBase::SHORT:
    case itk::ImageIOBase::USHORT:
      itk::ByteSwapper<short>::SwapRangeFromSystemToLittleEndian((short*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::INT:
    case itk::ImageIOBase::UINT:
      itk::ByteSwapper<int>::SwapRangeFromSystemToLittleEndian((int*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::LONG:
    case itk::ImageIOBase::ULONG:
      itk::ByteSwapper<long>::SwapRangeFromSystemToLittleEndian((long*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::FLOAT:
      itk::ByteSwapper<float>::SwapRangeFromSystemToLittleEndian((float*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::DOUBLE:
      itk::ByteSwapper<double>::SwapRangeFromSystemToLittleEndian(
        (double*)out, num_scalars);
      break;
    }

    imgMsg->Pack();

    output->SetMessage(imgMsg.GetPointer());
  }
}

void mitk::ImageToIGTLMessageFilter::SetInput(const mitk::Image* img)
{
  this->ProcessObject::SetNthInput(0, const_cast<mitk::Image*>(img));
  this->CreateOutputsForAllInputs();
}

void mitk::ImageToIGTLMessageFilter::SetInput(unsigned int idx,
  const Image* img)
{
  this->ProcessObject::SetNthInput(idx, const_cast<mitk::Image*>(img));
  this->CreateOutputsForAllInputs();
}

const mitk::Image* mitk::ImageToIGTLMessageFilter::GetInput(void)
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::Image*>(this->ProcessObject::GetInput(0));
}

const mitk::Image* mitk::ImageToIGTLMessageFilter::GetInput(unsigned int idx)
{
  if (this->GetNumberOfInputs() < idx + 1)
  {
    return NULL;
  }
  return static_cast<const mitk::Image*>(this->ProcessObject::GetInput(idx));
}

void mitk::ImageToIGTLMessageFilter::ConnectTo(mitk::ImageSource* upstream)
{
  MITK_INFO << "Image source for this (" << this << ") mitkImageToIGTLMessageFilter is " << upstream;
  for (DataObjectPointerArraySizeType i = 0; i < upstream->GetNumberOfOutputs();
    i++)
  {
    this->SetInput(i, upstream->GetOutput(i));
  }
}

void mitk::ImageToIGTLMessageFilter::CreateOutputsForAllInputs()
{
  // create one message output for all image inputs
  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());

  for (size_t idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx)
  {
    if (this->GetOutput(idx) == NULL)
    {
      this->SetNthOutput(idx, this->MakeOutput(idx));
    }
    this->Modified();
  }
}
<commit_msg>Fixed timestamp for images (was not set before)<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkImageToIGTLMessageFilter.h"
#include "mitkImageReadAccessor.h"
#include "itkByteSwapper.h"
#include "igtlImageMessage.h"

mitk::ImageToIGTLMessageFilter::ImageToIGTLMessageFilter()
{
  mitk::IGTLMessage::Pointer output = mitk::IGTLMessage::New();
  this->SetNumberOfRequiredOutputs(1);
  this->SetNthOutput(0, output.GetPointer());
  this->SetNumberOfRequiredInputs(1);
}

void mitk::ImageToIGTLMessageFilter::GenerateData()
{
  // MITK_INFO << "ImageToIGTLMessageFilter.GenerateData()";
  for (unsigned int i = 0; i < this->GetNumberOfIndexedOutputs(); ++i)
  {
    mitk::IGTLMessage* output = this->GetOutput(i);
    assert(output);

    const mitk::Image* img = this->GetInput(i);

    int dims = img->GetDimension();
    int chn = img->GetNumberOfChannels();

    if (dims < 1)
    {
      MITK_ERROR << "Can not handle dimensionless images";
    }
    if (dims > 3)
    {
      MITK_ERROR << "Can not handle more than three dimensions";
      continue;
    }

    if (chn != 1)
    {
      MITK_ERROR << "Can not handle anything but one channel. Image contained " << chn;
      continue;
    }

    igtl::ImageMessage::Pointer imgMsg = igtl::ImageMessage::New();

    // TODO: Which kind of coordinate system does MITK really use?
    imgMsg->SetCoordinateSystem(igtl::ImageMessage::COORDINATE_RAS);

    // We could do this based on the host endiannes, but that's weird.
    // We instead use little endian, as most modern systems are little endian,
    // so there will probably not be an endian swap involved.
    imgMsg->SetEndian(igtl::ImageMessage::ENDIAN_LITTLE);

    // Set number of components.
    mitk::PixelType type = img->GetPixelType();
    imgMsg->SetNumComponents(type.GetNumberOfComponents());

    // Set scalar type.
    switch (type.GetComponentType())
    {
    case itk::ImageIOBase::CHAR:
      imgMsg->SetScalarTypeToInt8();
      break;
    case itk::ImageIOBase::UCHAR:
      imgMsg->SetScalarTypeToUint8();
      break;
    case itk::ImageIOBase::SHORT:
      imgMsg->SetScalarTypeToInt16();
      break;
    case itk::ImageIOBase::USHORT:
      imgMsg->SetScalarTypeToUint16();
      break;
    case itk::ImageIOBase::INT:
      imgMsg->SetScalarTypeToInt32();
      break;
    case itk::ImageIOBase::UINT:
      imgMsg->SetScalarTypeToUint32();
      break;
    case itk::ImageIOBase::LONG:
      // OIGTL doesn't formally support 64bit int scalars, but if they are
      // ever added,
      // they will have the identifier 8 assigned.
      imgMsg->SetScalarType(8);
      break;
    case itk::ImageIOBase::ULONG:
      // OIGTL doesn't formally support 64bit uint scalars, but if they are
      // ever added,
      // they will have the identifier 9 assigned.
      imgMsg->SetScalarType(9);
      break;
    case itk::ImageIOBase::FLOAT:
      // The igtl library has no method for this. Correct type is 10.
      imgMsg->SetScalarType(10);
      break;
    case itk::ImageIOBase::DOUBLE:
      // The igtl library has no method for this. Correct type is 11.
      imgMsg->SetScalarType(11);
      break;
    default:
      MITK_ERROR << "Can not handle pixel component type "
        << type.GetComponentType();
      return;
    }

    // Set transformation matrix.
    vtkMatrix4x4* matrix = img->GetGeometry()->GetVtkMatrix();

    float matF[4][4];
    for (size_t i = 0; i < 4; ++i)
    {
      for (size_t j = 0; j < 4; ++j)
      {
        matF[i][j] = matrix->GetElement(i, j);
      }
    }
    imgMsg->SetMatrix(matF);

    float spacing[3];
    auto spacingImg = img->GetGeometry()->GetSpacing();

    for (int i = 0; i < 3; ++i)
      spacing[i] = spacingImg[i];

    imgMsg->SetSpacing(spacing);

    // Set dimensions.
    int sizes[3];
    for (size_t j = 0; j < 3; ++j)
    {
      sizes[j] = img->GetDimension(j);
    }
    imgMsg->SetDimensions(sizes);

    // Allocate and copy data.
    imgMsg->AllocatePack();
    imgMsg->AllocateScalars();

    size_t num_pixel = sizes[0] * sizes[1] * sizes[2];
    void* out = imgMsg->GetScalarPointer();
    {
      // Scoped, so that readAccess will be released ASAP.
      mitk::ImageReadAccessor readAccess(img, img->GetChannelData(0));
      const void* in = readAccess.GetData();

      memcpy(out, in, num_pixel * type.GetSize());
    }

    // We want to byte swap to little endian. We would like to just
    // swap by number of bytes for each component, but itk::ByteSwapper
    // is templated over element type, not over element size. So we need to
    // switch on the size and use types of the same size.
    size_t num_scalars = num_pixel * type.GetNumberOfComponents();
    switch (type.GetComponentType())
    {
    case itk::ImageIOBase::CHAR:
    case itk::ImageIOBase::UCHAR:
      // No endian conversion necessary, because a char is exactly one byte!
      break;
    case itk::ImageIOBase::SHORT:
    case itk::ImageIOBase::USHORT:
      itk::ByteSwapper<short>::SwapRangeFromSystemToLittleEndian((short*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::INT:
    case itk::ImageIOBase::UINT:
      itk::ByteSwapper<int>::SwapRangeFromSystemToLittleEndian((int*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::LONG:
    case itk::ImageIOBase::ULONG:
      itk::ByteSwapper<long>::SwapRangeFromSystemToLittleEndian((long*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::FLOAT:
      itk::ByteSwapper<float>::SwapRangeFromSystemToLittleEndian((float*)out,
        num_scalars);
      break;
    case itk::ImageIOBase::DOUBLE:
      itk::ByteSwapper<double>::SwapRangeFromSystemToLittleEndian(
        (double*)out, num_scalars);
      break;
    }

    //copy timestamp of mitk image
    igtl::TimeStamp::Pointer timestamp = igtl::TimeStamp::New();
    timestamp->SetTime(img->GetMTime() / 1000, (int)(img->GetMTime()) % 1000);
    imgMsg->SetTimeStamp(timestamp);

    imgMsg->Pack();

    output->SetMessage(imgMsg.GetPointer());
  }
}

void mitk::ImageToIGTLMessageFilter::SetInput(const mitk::Image* img)
{
  this->ProcessObject::SetNthInput(0, const_cast<mitk::Image*>(img));
  this->CreateOutputsForAllInputs();
}

void mitk::ImageToIGTLMessageFilter::SetInput(unsigned int idx,
  const Image* img)
{
  this->ProcessObject::SetNthInput(idx, const_cast<mitk::Image*>(img));
  this->CreateOutputsForAllInputs();
}

const mitk::Image* mitk::ImageToIGTLMessageFilter::GetInput(void)
{
  if (this->GetNumberOfInputs() < 1)
    return NULL;
  return static_cast<const mitk::Image*>(this->ProcessObject::GetInput(0));
}

const mitk::Image* mitk::ImageToIGTLMessageFilter::GetInput(unsigned int idx)
{
  if (this->GetNumberOfInputs() < idx + 1)
  {
    return NULL;
  }
  return static_cast<const mitk::Image*>(this->ProcessObject::GetInput(idx));
}

void mitk::ImageToIGTLMessageFilter::ConnectTo(mitk::ImageSource* upstream)
{
  MITK_INFO << "Image source for this (" << this << ") mitkImageToIGTLMessageFilter is " << upstream;
  for (DataObjectPointerArraySizeType i = 0; i < upstream->GetNumberOfOutputs();
    i++)
  {
    this->SetInput(i, upstream->GetOutput(i));
  }
}

void mitk::ImageToIGTLMessageFilter::CreateOutputsForAllInputs()
{
  // create one message output for all image inputs
  this->SetNumberOfIndexedOutputs(this->GetNumberOfIndexedInputs());

  for (size_t idx = 0; idx < this->GetNumberOfIndexedOutputs(); ++idx)
  {
    if (this->GetOutput(idx) == NULL)
    {
      this->SetNthOutput(idx, this->MakeOutput(idx));
    }
    this->Modified();
  }
}
<|endoftext|>


<commit_before>// https://de.wikipedia.org/wiki/Internationale_Bankkontonummer#Zusammensetzung

#include<iostream>
#include<string>
#include<regex>
#include<boost/multiprecision/gmp.hpp>

void usage() {
    std::cout << "iban <iban>" << std::endl
              << std::endl
              << "check iban" << std::endl;
}

std::string convert_lc(const std::string& lc) {
    static auto conv_digit = [=](char c) -> std::string {
        auto tmp = c - 'A' + 10;
        return std::to_string(tmp);
    };
    return conv_digit(lc[0]) + conv_digit(lc[1]);
}

int main(int argn, char* argv[]) {
    if (argn == 1) {
        usage();
        exit(1);
    }
    std::string iban = argv[1];
    const std::regex re ("[A-Z][A-Z]\\d{20}", std::regex::icase);
    if (! std::regex_match(iban, re)) {
        std::cout << "IBAN ist falsch formatiert" << std::endl;
    }
    const std::regex ree("^(..)(..)(.+)$");
    std::smatch m;
    if (std::regex_match(iban, m, ree)) {
        auto lc = m[1].str();
        auto pz = m[2].str();
        auto rest = m[3].str();
        std::cout << "LC: " << lc << std::endl;
        std::cout << "PZ: " << pz << std::endl;
        std::cout << "Rest: " << rest << std::endl;
        auto lcdigits = convert_lc(lc);
        std::cout << "LC digits: " << lcdigits << std::endl;
        using namespace std::string_literals;
        boost::multiprecision::mpz_int i{rest + lcdigits + "00"s};
        boost::multiprecision::mpz_int calc_pz = 98 - (i % 97);
        auto calc_pz_str = calc_pz.convert_to<std::string>();
        std::cout << "98 - (" << i << " % 97) = " << calc_pz_str << std::endl;
        auto res = pz == calc_pz_str;
        std::cout << "Die Prüfziffern stimmen" << ( res ? "." : " nicht!") << std::endl;
    }
}
<commit_msg>20190714_2<commit_after>// https://de.wikipedia.org/wiki/Internationale_Bankkontonummer#Zusammensetzung

#include<iostream>
#include<string>
#include<regex>
#include<boost/multiprecision/gmp.hpp>

void usage() {
    std::cout << "iban <iban>" << std::endl
              << std::endl
              << "check iban" << std::endl;
}

std::string convert_lc(const std::string& lc) {
    static auto conv_digit = [=](char c) -> std::string {
        auto tmp = c - 'A' + 10;
        return std::to_string(tmp);
    };
    return conv_digit(lc[0]) + conv_digit(lc[1]);
}

int check_iban(const std::string iban) {
    int ret = 0;
    std::cout << "=== Checking " << iban << "===" << std::endl;
    const std::regex re ("[A-Z][A-Z]\\d{20}", std::regex::icase);
    if (! std::regex_match(iban, re)) {
        std::cout << "IBAN ist falsch formatiert" << std::endl;
        ret = 1;
    }
    const std::regex ree("^(..)(..)(.+)$");
    std::smatch m;
    if (std::regex_match(iban, m, ree)) {
        auto lc = m[1].str();
        auto pz = m[2].str();
        auto rest = m[3].str();
        std::cout << "LC: " << lc << std::endl;
        std::cout << "PZ: " << pz << std::endl;
        std::cout << "Rest: " << rest << std::endl;
        auto lcdigits = convert_lc(lc);
        std::cout << "LC digits: " << lcdigits << std::endl;
        using namespace std::string_literals;
        boost::multiprecision::mpz_int i{rest + lcdigits + "00"s};
        boost::multiprecision::mpz_int calc_pz = 98 - (i % 97);
        auto calc_pz_str = calc_pz.convert_to<std::string>();
        std::cout << "98 - (" << i << " % 97) = " << calc_pz_str << std::endl;
        auto res = pz == calc_pz_str;
        std::cout << "Die Prüfziffern stimmen" << ( res ? "." : " nicht!") << std::endl;
        if (!res)
            ret = 1;
    }
    return ret;
}

// ./iban DE5837040044028465250 DE58370400440284652500
int main(int argn, char* argv[]) {
    std::ios_base::sync_with_stdio(false);
    if (argn == 1) {
        usage();
        exit(1);
    }
    int ret = 0;
    for (int i = 1; i < argn; ++i) {
        ret = std::max(ret, check_iban(argv[i]));
    }
    return ret;
}
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"

#include "DebugOperatorNew.h"

#include "QtModule.h"

#include <Ogre.h>
#include "OgreRenderingModule.h"
#include "RendererEvents.h"

#include <QGraphicsScene>
#include <QDebug>
#include <QApplication>

#include "InputEvents.h"
#include "InputModuleOIS.h"

#include "MemoryLeakCheck.h"

namespace QtUI
{

namespace
{
    const std::string moduleName("QtModule");
}

QtModule::QtModule()
:ModuleInterfaceImpl(Foundation::Module::MT_Gui), controller_(0)
{
}

QtModule::~QtModule()
{
}

void QtModule::Load()
{
}

void QtModule::Unload()
{
}

void QtModule::PreInitialize()
{
}

void QtModule::Initialize()
{
    // Sanity check
    SAFE_DELETE(controller_);

    controller_ = new UIController;

    boost::shared_ptr<OgreRenderer::Renderer> renderer = framework_->GetServiceManager()->GetService
        <OgreRenderer::Renderer>(Foundation::Service::ST_Renderer).lock();

    if (!renderer)
        throw Core::Exception("Error! Could not find renderer service!");

    controller_->SetParentWindowSize(QSize(renderer->GetWindowWidth(), renderer->GetWindowHeight()));

    //Initialize OISKeyCode map.
    InitializeKeyCodes();

    mouse_left_button_down_ = false;
}

void QtModule::PostInitialize()
{
    Foundation::EventManagerPtr event_manager = framework_->GetEventManager();
    input_event_category_ = event_manager->QueryEventCategory("Input");
    renderer_event_category_ = event_manager->QueryEventCategory("Renderer");
}

void QtModule::Uninitialize()
{
    SAFE_DELETE(controller_);
}

bool QtModule::HandleEvent(Core::event_category_id_t category_id,
    Core::event_id_t event_id,
    Foundation::EventDataInterface* data)
{
    ///\todo Currently OIS mouse is polled in Update(). Convert all input to come through here.
    /// Requires that we can track when a canvas needs to be redrawn due to visual changes on mouse hover.
/*  if (category_id == input_event_category_ && event_id == Input::Events::INWORLD_CLICK)
    {
        Input::Events::Movement *movement = checked_static_cast<Input::Events::Movement*>(data);
        main_view_->InjectMousePress(movement->x_.abs_, movement->y_.abs_);
    } */

    if (category_id == renderer_event_category_ && event_id == OgreRenderer::Events::WINDOW_RESIZED)
    {
        // To properly compute the relative overlay sizes and positions for canvases, we need to keep track of the
        // absolute size of the render window. Update the render window size on each WINDOW_RESIZED message.
        OgreRenderer::Events::WindowResized *windowResized = checked_static_cast<OgreRenderer::Events::WindowResized *>(data);
        controller_->SetParentWindowSize(QSize(windowResized->width_, windowResized->height_));
    }
    else if (category_id == input_event_category_ && (event_id == Input::Events::BUFFERED_KEY_PRESSED ||event_id == Input::Events::BUFFERED_KEY_RELEASED))
    {
        boost::weak_ptr<Input::InputModuleOIS> inputWeak =
            framework_->GetModuleManager()->GetModule<Input::InputModuleOIS>(Foundation::Module::MT_Input).lock();
        boost::shared_ptr<Input::InputModuleOIS> input = inputWeak.lock();
        if (input.get() == 0)
            return false;

        // Get the key event OIS sent and convert it to a Qt key event.
        Input::Events::BufferedKey *key = checked_static_cast<Input::Events::BufferedKey* >(data);

        Qt::Key value;
        if (converterMap_.contains(static_cast<int>(key->code_)))
            value = converterMap_[static_cast<int>(key->code_)];
        else
            value = Qt::Key_unknown;

        ///\todo Are we missing the handling of Ctrl,Alt,AltGr,Win,Shift modifiers on keys?
//        Qt::KeyboardModifier modifier = Qt::NoModifier;

        // Inject the key event to the controller. It will propagate the event to the currently active canvas.
        if (event_id == Input::Events::BUFFERED_KEY_PRESSED)
            controller_->InjectKeyPressed(QString(QChar(key->text_)), value);
        else
            controller_->InjectKeyReleased(QString(QChar(key->text_)), value);
    }

    return false;
}

boost::weak_ptr<UICanvas> QtModule::CreateCanvas(UICanvas::Mode mode)
{
    boost::shared_ptr<UICanvas> canvas = controller_->CreateCanvas(mode).lock();
//    canvas->setParent(framework_->GetApplicationMainWindowQWidget());
    return canvas;
}

void QtModule::Update(Core::f64 frametime)
{
    boost::shared_ptr<OgreRenderer::Renderer> renderer = framework_->GetServiceManager()->GetService
        <OgreRenderer::Renderer>(Foundation::Service::ST_Renderer).lock();
    if (!renderer)
        return;

    {
        PROFILE(QtModule_Update);

        // Poll mouse input from OIS.

        ///\todo Remove this in favor of events.
        boost::weak_ptr<Input::InputModuleOIS> inputWeak =
            framework_->GetModuleManager()->GetModule<Input::InputModuleOIS>(Foundation::Module::MT_Input).lock();

        boost::shared_ptr<Input::InputModuleOIS> input = inputWeak.lock();

        if (!input.get())
            return;

        const Input::Events::Movement &mouse = input->GetMouseMovement();
        QPointF pos = QPointF(mouse.x_.abs_, mouse.y_.abs_);
        QPoint change = lastPos_ - pos.toPoint();

        if (input->IsButtonDown(OIS::MB_Left) && !mouse_left_button_down_)
        {
            if (controller_->GetCanvasAt(pos.x(), pos.y()))
                framework_->GetQApplication()->setActiveWindow(controller_->GetCanvasAt(pos.x(), pos.y()));
            controller_->InjectMousePress(pos.x(), pos.y());

            if ( controller_->IsKeyboardFocus() && input->GetState() != Input::State_Buffered)
                input->SetState(Input::State_Buffered);
            else
                input->SetState(Input::State_Unknown);

            mouse_left_button_down_ = true;
        }
        else if (!input->IsButtonDown(OIS::MB_Left) && mouse_left_button_down_)
        {
            controller_->InjectMouseRelease(pos.x(),pos.y());
            mouse_left_button_down_ = false;
        }
        else if ( change.manhattanLength() >= 1 )
        {
            controller_->InjectMouseMove(pos.x(),pos.y());
        }
        lastPos_ = pos.toPoint();

        PROFILE(QtSceneRender);

        ///\todo Optimize to redraw only those rectangles that are dirty.

        controller_->Update();
    }
    RESETPROFILER;
}

const std::string &QtModule::NameStatic()
{
    return moduleName;
}

void QtModule::InitializeKeyCodes()
{
    /* OIS gives us hardware keyboard scan codes, but Qt has its own code system where characters are
        represented either in ascii, or if there's no equivalent, using a custom ID. Currently the
        only way we know of how to handle this is to perform a manual mapping between these two.

        The following keys haven't been mapped to any OIS input (see http://doc.trolltech.com/4.5/qt.html#Key-enum):
        Qt::Key_AltGr,
        Qt::Key_F16 - Qt::Key_F35
        All keys between: Qt::Key_Super_L - Qt::Key_Direction_R except Qt::Key_Menu
        Qt::Key_Any,
        Qt::Key_Exclam,
        Qt::Key_QuoteDbl,
        Qt::Key_NumberSign,
        Qt::Key_Dollar,
        Qt::Key_Percent,
        Qt::Key_Ampersand,
        Qt::Key_ParenLeft,
        Qt::Key_ParenRight
        Qt::Key_Less
        Qt::Key_Greater
        Qt::Key_Question
    */

    converterMap_.insert(OIS::KC_ESCAPE, Qt::Key_Escape);
    converterMap_.insert(OIS::KC_TAB, Qt::Key_Tab);
    converterMap_.insert(OIS::KC_BACK, Qt::Key_Backspace);
    converterMap_.insert(OIS::KC_RETURN, Qt::Key_Return);
    converterMap_.insert(OIS::KC_NUMPADENTER, Qt::Key_Enter);
    converterMap_.insert(OIS::KC_INSERT, Qt::Key_Insert);
    converterMap_.insert(OIS::KC_DELETE, Qt::Key_Delete);
    converterMap_.insert(OIS::KC_PAUSE, Qt::Key_Pause);
    converterMap_.insert(OIS::KC_SYSRQ, Qt::Key_SysReq);
    converterMap_.insert(OIS::KC_HOME, Qt::Key_Home);
    converterMap_.insert(OIS::KC_END, Qt::Key_End);
    converterMap_.insert(OIS::KC_LEFT, Qt::Key_Left);
    converterMap_.insert(OIS::KC_UP, Qt::Key_Up);
    converterMap_.insert(OIS::KC_RIGHT, Qt::Key_Right);
    converterMap_.insert(OIS::KC_DOWN, Qt::Key_Down);
    converterMap_.insert(OIS::KC_PGUP, Qt::Key_PageUp);
    converterMap_.insert(OIS::KC_PGDOWN, Qt::Key_PageDown);
    converterMap_.insert(OIS::KC_LSHIFT, Qt::Key_Shift);
    converterMap_.insert(OIS::KC_LCONTROL, Qt::Key_Control);
    converterMap_.insert(OIS::KC_LWIN, Qt::Key_Meta);
    converterMap_.insert(OIS::KC_LMENU, Qt::Key_Alt);
    converterMap_.insert(OIS::KC_CAPITAL, Qt::Key_CapsLock);
    converterMap_.insert(OIS::KC_NUMLOCK, Qt::Key_NumLock);
    converterMap_.insert(OIS::KC_SCROLL, Qt::Key_ScrollLock);
    converterMap_.insert(OIS::KC_F1, Qt::Key_F1);
    converterMap_.insert(OIS::KC_F2, Qt::Key_F2);
    converterMap_.insert(OIS::KC_F3, Qt::Key_F3);
    converterMap_.insert(OIS::KC_F4, Qt::Key_F4);
    converterMap_.insert(OIS::KC_F5, Qt::Key_F5);
    converterMap_.insert(OIS::KC_F6, Qt::Key_F6);
    converterMap_.insert(OIS::KC_F7, Qt::Key_F7);
    converterMap_.insert(OIS::KC_F8, Qt::Key_F8);
    converterMap_.insert(OIS::KC_F9, Qt::Key_F9);
    converterMap_.insert(OIS::KC_F10, Qt::Key_F10);
    converterMap_.insert(OIS::KC_F11, Qt::Key_F11);
    converterMap_.insert(OIS::KC_F12, Qt::Key_F12);
    converterMap_.insert(OIS::KC_F13, Qt::Key_F13);
    converterMap_.insert(OIS::KC_F14, Qt::Key_F14);
    converterMap_.insert(OIS::KC_F15, Qt::Key_F15);
    converterMap_.insert(OIS::KC_APPS, Qt::Key_Menu);
    converterMap_.insert(OIS::KC_SPACE, Qt::Key_Space);
    converterMap_.insert(OIS::KC_APOSTROPHE, Qt::Key_Apostrophe);
    converterMap_.insert(OIS::KC_MULTIPLY, Qt::Key_Asterisk);
    converterMap_.insert(OIS::KC_ADD, Qt::Key_Plus);
    converterMap_.insert(OIS::KC_COMMA, Qt::Key_Comma);
    converterMap_.insert(OIS::KC_MINUS, Qt::Key_Minus);
    converterMap_.insert(OIS::KC_PERIOD, Qt::Key_Period);
    converterMap_.insert(OIS::KC_SLASH, Qt::Key_Slash);
    converterMap_.insert(OIS::KC_0, Qt::Key_0);
    converterMap_.insert(OIS::KC_1, Qt::Key_1);
    converterMap_.insert(OIS::KC_2, Qt::Key_2);
    converterMap_.insert(OIS::KC_3, Qt::Key_3);
    converterMap_.insert(OIS::KC_4, Qt::Key_4);
    converterMap_.insert(OIS::KC_5, Qt::Key_5);
    converterMap_.insert(OIS::KC_6, Qt::Key_6);
    converterMap_.insert(OIS::KC_7, Qt::Key_7);
    converterMap_.insert(OIS::KC_8, Qt::Key_8);
    converterMap_.insert(OIS::KC_9, Qt::Key_9);
    converterMap_.insert(OIS::KC_COLON, Qt::Key_Colon);
    converterMap_.insert(OIS::KC_SEMICOLON , Qt::Key_Semicolon);
    converterMap_.insert(OIS::KC_EQUALS, Qt::Key_Equal);
    converterMap_.insert(OIS::KC_AT , Qt::Key_At);
    converterMap_.insert(OIS::KC_A , Qt::Key_A);
    converterMap_.insert(OIS::KC_B , Qt::Key_B);
    converterMap_.insert(OIS::KC_C , Qt::Key_C);
    converterMap_.insert(OIS::KC_D , Qt::Key_D);
    converterMap_.insert(OIS::KC_E , Qt::Key_E);
    converterMap_.insert(OIS::KC_F , Qt::Key_F);
    converterMap_.insert(OIS::KC_G , Qt::Key_G);
    converterMap_.insert(OIS::KC_H , Qt::Key_H);
    converterMap_.insert(OIS::KC_I , Qt::Key_I);
    converterMap_.insert(OIS::KC_J , Qt::Key_J);
    converterMap_.insert(OIS::KC_K , Qt::Key_K);
    converterMap_.insert(OIS::KC_L , Qt::Key_L);
    converterMap_.insert(OIS::KC_M , Qt::Key_M);
    converterMap_.insert(OIS::KC_N , Qt::Key_N);
    converterMap_.insert(OIS::KC_O , Qt::Key_O);
    converterMap_.insert(OIS::KC_P , Qt::Key_P);
    converterMap_.insert(OIS::KC_Q , Qt::Key_Q);
    converterMap_.insert(OIS::KC_R , Qt::Key_R);
    converterMap_.insert(OIS::KC_S , Qt::Key_S);
    converterMap_.insert(OIS::KC_T , Qt::Key_T);
    converterMap_.insert(OIS::KC_U , Qt::Key_U);
    converterMap_.insert(OIS::KC_V , Qt::Key_V);
    converterMap_.insert(OIS::KC_W , Qt::Key_W);
    converterMap_.insert(OIS::KC_X , Qt::Key_X);
    converterMap_.insert(OIS::KC_Y, Qt::Key_Y);
    converterMap_.insert(OIS::KC_Z , Qt::Key_Z);
    converterMap_.insert(OIS::KC_LBRACKET , Qt::Key_BracketLeft);
}

}

extern "C" void POCO_LIBRARY_API SetProfiler(Foundation::Profiler *profiler);
void SetProfiler(Foundation::Profiler *profiler)
{
    Foundation::ProfilerSection::SetProfiler(profiler);
}

using namespace QtUI;

POCO_BEGIN_MANIFEST(Foundation::ModuleInterface)
   POCO_EXPORT_CLASS(QtModule)
POCO_END_MANIFEST
<commit_msg>Comment out code that uses nonexisting function.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"

#include "DebugOperatorNew.h"

#include "QtModule.h"

#include <Ogre.h>
#include "OgreRenderingModule.h"
#include "RendererEvents.h"

#include <QGraphicsScene>
#include <QDebug>
#include <QApplication>

#include "InputEvents.h"
#include "InputModuleOIS.h"

#include "MemoryLeakCheck.h"

namespace QtUI
{

namespace
{
    const std::string moduleName("QtModule");
}

QtModule::QtModule()
:ModuleInterfaceImpl(Foundation::Module::MT_Gui), controller_(0)
{
}

QtModule::~QtModule()
{
}

void QtModule::Load()
{
}

void QtModule::Unload()
{
}

void QtModule::PreInitialize()
{
}

void QtModule::Initialize()
{
    // Sanity check
    SAFE_DELETE(controller_);

    controller_ = new UIController;

    boost::shared_ptr<OgreRenderer::Renderer> renderer = framework_->GetServiceManager()->GetService
        <OgreRenderer::Renderer>(Foundation::Service::ST_Renderer).lock();

    if (!renderer)
        throw Core::Exception("Error! Could not find renderer service!");

    controller_->SetParentWindowSize(QSize(renderer->GetWindowWidth(), renderer->GetWindowHeight()));

    //Initialize OISKeyCode map.
    InitializeKeyCodes();

    mouse_left_button_down_ = false;
}

void QtModule::PostInitialize()
{
    Foundation::EventManagerPtr event_manager = framework_->GetEventManager();
    input_event_category_ = event_manager->QueryEventCategory("Input");
    renderer_event_category_ = event_manager->QueryEventCategory("Renderer");
}

void QtModule::Uninitialize()
{
    SAFE_DELETE(controller_);
}

bool QtModule::HandleEvent(Core::event_category_id_t category_id,
    Core::event_id_t event_id,
    Foundation::EventDataInterface* data)
{
    ///\todo Currently OIS mouse is polled in Update(). Convert all input to come through here.
    /// Requires that we can track when a canvas needs to be redrawn due to visual changes on mouse hover.
/*  if (category_id == input_event_category_ && event_id == Input::Events::INWORLD_CLICK)
    {
        Input::Events::Movement *movement = checked_static_cast<Input::Events::Movement*>(data);
        main_view_->InjectMousePress(movement->x_.abs_, movement->y_.abs_);
    } */

    if (category_id == renderer_event_category_ && event_id == OgreRenderer::Events::WINDOW_RESIZED)
    {
        // To properly compute the relative overlay sizes and positions for canvases, we need to keep track of the
        // absolute size of the render window. Update the render window size on each WINDOW_RESIZED message.
        OgreRenderer::Events::WindowResized *windowResized = checked_static_cast<OgreRenderer::Events::WindowResized *>(data);
        controller_->SetParentWindowSize(QSize(windowResized->width_, windowResized->height_));
    }
    else if (category_id == input_event_category_ && (event_id == Input::Events::BUFFERED_KEY_PRESSED ||event_id == Input::Events::BUFFERED_KEY_RELEASED))
    {
        boost::weak_ptr<Input::InputModuleOIS> inputWeak =
            framework_->GetModuleManager()->GetModule<Input::InputModuleOIS>(Foundation::Module::MT_Input).lock();
        boost::shared_ptr<Input::InputModuleOIS> input = inputWeak.lock();
        if (input.get() == 0)
            return false;

        // Get the key event OIS sent and convert it to a Qt key event.
        Input::Events::BufferedKey *key = checked_static_cast<Input::Events::BufferedKey* >(data);

        Qt::Key value;
        if (converterMap_.contains(static_cast<int>(key->code_)))
            value = converterMap_[static_cast<int>(key->code_)];
        else
            value = Qt::Key_unknown;

        ///\todo Are we missing the handling of Ctrl,Alt,AltGr,Win,Shift modifiers on keys?
//        Qt::KeyboardModifier modifier = Qt::NoModifier;

        // Inject the key event to the controller. It will propagate the event to the currently active canvas.
        if (event_id == Input::Events::BUFFERED_KEY_PRESSED)
            controller_->InjectKeyPressed(QString(QChar(key->text_)), value);
        else
            controller_->InjectKeyReleased(QString(QChar(key->text_)), value);
    }

    return false;
}

boost::weak_ptr<UICanvas> QtModule::CreateCanvas(UICanvas::Mode mode)
{
    boost::shared_ptr<UICanvas> canvas = controller_->CreateCanvas(mode).lock();
//    canvas->setParent(framework_->GetApplicationMainWindowQWidget());
    return canvas;
}

void QtModule::Update(Core::f64 frametime)
{
    boost::shared_ptr<OgreRenderer::Renderer> renderer = framework_->GetServiceManager()->GetService
        <OgreRenderer::Renderer>(Foundation::Service::ST_Renderer).lock();
    if (!renderer)
        return;

    {
        PROFILE(QtModule_Update);

        // Poll mouse input from OIS.

        ///\todo Remove this in favor of events.
        boost::weak_ptr<Input::InputModuleOIS> inputWeak =
            framework_->GetModuleManager()->GetModule<Input::InputModuleOIS>(Foundation::Module::MT_Input).lock();

        boost::shared_ptr<Input::InputModuleOIS> input = inputWeak.lock();

        if (!input.get())
            return;

        const Input::Events::Movement &mouse = input->GetMouseMovement();
        QPointF pos = QPointF(mouse.x_.abs_, mouse.y_.abs_);
        QPoint change = lastPos_ - pos.toPoint();

        if (input->IsButtonDown(OIS::MB_Left) && !mouse_left_button_down_)
        {
//            if (controller_->GetCanvasAt(pos.x(), pos.y()))
//                framework_->GetQApplication()->setActiveWindow(controller_->GetCanvasAt(pos.x(), pos.y()));
            controller_->InjectMousePress(pos.x(), pos.y());

            if ( controller_->IsKeyboardFocus() && input->GetState() != Input::State_Buffered)
                input->SetState(Input::State_Buffered);
            else
                input->SetState(Input::State_Unknown);

            mouse_left_button_down_ = true;
        }
        else if (!input->IsButtonDown(OIS::MB_Left) && mouse_left_button_down_)
        {
            controller_->InjectMouseRelease(pos.x(),pos.y());
            mouse_left_button_down_ = false;
        }
        else if ( change.manhattanLength() >= 1 )
        {
            controller_->InjectMouseMove(pos.x(),pos.y());
        }
        lastPos_ = pos.toPoint();

        PROFILE(QtSceneRender);

        ///\todo Optimize to redraw only those rectangles that are dirty.

        controller_->Update();
    }
    RESETPROFILER;
}

const std::string &QtModule::NameStatic()
{
    return moduleName;
}

void QtModule::InitializeKeyCodes()
{
    /* OIS gives us hardware keyboard scan codes, but Qt has its own code system where characters are
        represented either in ascii, or if there's no equivalent, using a custom ID. Currently the
        only way we know of how to handle this is to perform a manual mapping between these two.

        The following keys haven't been mapped to any OIS input (see http://doc.trolltech.com/4.5/qt.html#Key-enum):
        Qt::Key_AltGr,
        Qt::Key_F16 - Qt::Key_F35
        All keys between: Qt::Key_Super_L - Qt::Key_Direction_R except Qt::Key_Menu
        Qt::Key_Any,
        Qt::Key_Exclam,
        Qt::Key_QuoteDbl,
        Qt::Key_NumberSign,
        Qt::Key_Dollar,
        Qt::Key_Percent,
        Qt::Key_Ampersand,
        Qt::Key_ParenLeft,
        Qt::Key_ParenRight
        Qt::Key_Less
        Qt::Key_Greater
        Qt::Key_Question
    */

    converterMap_.insert(OIS::KC_ESCAPE, Qt::Key_Escape);
    converterMap_.insert(OIS::KC_TAB, Qt::Key_Tab);
    converterMap_.insert(OIS::KC_BACK, Qt::Key_Backspace);
    converterMap_.insert(OIS::KC_RETURN, Qt::Key_Return);
    converterMap_.insert(OIS::KC_NUMPADENTER, Qt::Key_Enter);
    converterMap_.insert(OIS::KC_INSERT, Qt::Key_Insert);
    converterMap_.insert(OIS::KC_DELETE, Qt::Key_Delete);
    converterMap_.insert(OIS::KC_PAUSE, Qt::Key_Pause);
    converterMap_.insert(OIS::KC_SYSRQ, Qt::Key_SysReq);
    converterMap_.insert(OIS::KC_HOME, Qt::Key_Home);
    converterMap_.insert(OIS::KC_END, Qt::Key_End);
    converterMap_.insert(OIS::KC_LEFT, Qt::Key_Left);
    converterMap_.insert(OIS::KC_UP, Qt::Key_Up);
    converterMap_.insert(OIS::KC_RIGHT, Qt::Key_Right);
    converterMap_.insert(OIS::KC_DOWN, Qt::Key_Down);
    converterMap_.insert(OIS::KC_PGUP, Qt::Key_PageUp);
    converterMap_.insert(OIS::KC_PGDOWN, Qt::Key_PageDown);
    converterMap_.insert(OIS::KC_LSHIFT, Qt::Key_Shift);
    converterMap_.insert(OIS::KC_LCONTROL, Qt::Key_Control);
    converterMap_.insert(OIS::KC_LWIN, Qt::Key_Meta);
    converterMap_.insert(OIS::KC_LMENU, Qt::Key_Alt);
    converterMap_.insert(OIS::KC_CAPITAL, Qt::Key_CapsLock);
    converterMap_.insert(OIS::KC_NUMLOCK, Qt::Key_NumLock);
    converterMap_.insert(OIS::KC_SCROLL, Qt::Key_ScrollLock);
    converterMap_.insert(OIS::KC_F1, Qt::Key_F1);
    converterMap_.insert(OIS::KC_F2, Qt::Key_F2);
    converterMap_.insert(OIS::KC_F3, Qt::Key_F3);
    converterMap_.insert(OIS::KC_F4, Qt::Key_F4);
    converterMap_.insert(OIS::KC_F5, Qt::Key_F5);
    converterMap_.insert(OIS::KC_F6, Qt::Key_F6);
    converterMap_.insert(OIS::KC_F7, Qt::Key_F7);
    converterMap_.insert(OIS::KC_F8, Qt::Key_F8);
    converterMap_.insert(OIS::KC_F9, Qt::Key_F9);
    converterMap_.insert(OIS::KC_F10, Qt::Key_F10);
    converterMap_.insert(OIS::KC_F11, Qt::Key_F11);
    converterMap_.insert(OIS::KC_F12, Qt::Key_F12);
    converterMap_.insert(OIS::KC_F13, Qt::Key_F13);
    converterMap_.insert(OIS::KC_F14, Qt::Key_F14);
    converterMap_.insert(OIS::KC_F15, Qt::Key_F15);
    converterMap_.insert(OIS::KC_APPS, Qt::Key_Menu);
    converterMap_.insert(OIS::KC_SPACE, Qt::Key_Space);
    converterMap_.insert(OIS::KC_APOSTROPHE, Qt::Key_Apostrophe);
    converterMap_.insert(OIS::KC_MULTIPLY, Qt::Key_Asterisk);
    converterMap_.insert(OIS::KC_ADD, Qt::Key_Plus);
    converterMap_.insert(OIS::KC_COMMA, Qt::Key_Comma);
    converterMap_.insert(OIS::KC_MINUS, Qt::Key_Minus);
    converterMap_.insert(OIS::KC_PERIOD, Qt::Key_Period);
    converterMap_.insert(OIS::KC_SLASH, Qt::Key_Slash);
    converterMap_.insert(OIS::KC_0, Qt::Key_0);
    converterMap_.insert(OIS::KC_1, Qt::Key_1);
    converterMap_.insert(OIS::KC_2, Qt::Key_2);
    converterMap_.insert(OIS::KC_3, Qt::Key_3);
    converterMap_.insert(OIS::KC_4, Qt::Key_4);
    converterMap_.insert(OIS::KC_5, Qt::Key_5);
    converterMap_.insert(OIS::KC_6, Qt::Key_6);
    converterMap_.insert(OIS::KC_7, Qt::Key_7);
    converterMap_.insert(OIS::KC_8, Qt::Key_8);
    converterMap_.insert(OIS::KC_9, Qt::Key_9);
    converterMap_.insert(OIS::KC_COLON, Qt::Key_Colon);
    converterMap_.insert(OIS::KC_SEMICOLON , Qt::Key_Semicolon);
    converterMap_.insert(OIS::KC_EQUALS, Qt::Key_Equal);
    converterMap_.insert(OIS::KC_AT , Qt::Key_At);
    converterMap_.insert(OIS::KC_A , Qt::Key_A);
    converterMap_.insert(OIS::KC_B , Qt::Key_B);
    converterMap_.insert(OIS::KC_C , Qt::Key_C);
    converterMap_.insert(OIS::KC_D , Qt::Key_D);
    converterMap_.insert(OIS::KC_E , Qt::Key_E);
    converterMap_.insert(OIS::KC_F , Qt::Key_F);
    converterMap_.insert(OIS::KC_G , Qt::Key_G);
    converterMap_.insert(OIS::KC_H , Qt::Key_H);
    converterMap_.insert(OIS::KC_I , Qt::Key_I);
    converterMap_.insert(OIS::KC_J , Qt::Key_J);
    converterMap_.insert(OIS::KC_K , Qt::Key_K);
    converterMap_.insert(OIS::KC_L , Qt::Key_L);
    converterMap_.insert(OIS::KC_M , Qt::Key_M);
    converterMap_.insert(OIS::KC_N , Qt::Key_N);
    converterMap_.insert(OIS::KC_O , Qt::Key_O);
    converterMap_.insert(OIS::KC_P , Qt::Key_P);
    converterMap_.insert(OIS::KC_Q , Qt::Key_Q);
    converterMap_.insert(OIS::KC_R , Qt::Key_R);
    converterMap_.insert(OIS::KC_S , Qt::Key_S);
    converterMap_.insert(OIS::KC_T , Qt::Key_T);
    converterMap_.insert(OIS::KC_U , Qt::Key_U);
    converterMap_.insert(OIS::KC_V , Qt::Key_V);
    converterMap_.insert(OIS::KC_W , Qt::Key_W);
    converterMap_.insert(OIS::KC_X , Qt::Key_X);
    converterMap_.insert(OIS::KC_Y, Qt::Key_Y);
    converterMap_.insert(OIS::KC_Z , Qt::Key_Z);
    converterMap_.insert(OIS::KC_LBRACKET , Qt::Key_BracketLeft);
}

}

extern "C" void POCO_LIBRARY_API SetProfiler(Foundation::Profiler *profiler);
void SetProfiler(Foundation::Profiler *profiler)
{
    Foundation::ProfilerSection::SetProfiler(profiler);
}

using namespace QtUI;

POCO_BEGIN_MANIFEST(Foundation::ModuleInterface)
   POCO_EXPORT_CLASS(QtModule)
POCO_END_MANIFEST
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_STYLE_PROCESSOR_HPP
#define FEATURE_STYLE_PROCESSOR_HPP

// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/memory_datasource.hpp>

#ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp>
#endif
// boost
#include <boost/foreach.hpp>
//stl
#include <vector>

namespace mapnik
{

template <typename Processor>
class feature_style_processor
{
    /** Calls the renderer's process function,
      * \param output     Renderer
      * \param f          Feature to process
      * \param prj_trans  Projection
      * \param sym        Symbolizer object
      */
    struct symbol_dispatch : public boost::static_visitor<>
    {
        symbol_dispatch (Processor & output,
                         Feature const& f,
                         proj_transform const& prj_trans)
            : output_(output),
              f_(f),
              prj_trans_(prj_trans)  {}

        template <typename T>
        void operator () (T const& sym) const
        {
            output_.process(sym,f_,prj_trans_);
        }

        Processor & output_;
        Feature const& f_;
        proj_transform const& prj_trans_;
    };
public:
    explicit feature_style_processor(Map const& m, double scale_factor = 1.0)
        : m_(m),
          scale_factor_(scale_factor) {}

    void apply()
    {
#ifdef MAPNIK_DEBUG
        //mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
#endif
        Processor & p = static_cast<Processor&>(*this);
        p.start_map_processing(m_);

        try
        {
            projection proj(m_.srs()); // map projection

            Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
            Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->set_size(m_.width(), m_.height());
                metaItr->second->set_map_srs(proj);
                metaItr->second->start(m_.metawriter_output_properties);
            }

            double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
            scale_denom *= scale_factor_;
#ifdef MAPNIK_DEBUG
            std::clog << "scale denominator = " << scale_denom << "\n";
#endif
            BOOST_FOREACH ( layer const& lyr, m_.layers() )
            {
                if (lyr.isVisible(scale_denom))
                {
                    apply_to_layer(lyr, p, proj, scale_denom);
                }
            }

            metaItr = m_.begin_metawriters();
            for (;metaItr!=metaItrEnd; ++metaItr)
            {
                metaItr->second->stop();
            }
        }
        catch (proj_init_error& ex)
        {
            std::clog << "proj_init_error:" << ex.what() << "\n";
        }

        p.end_map_processing(m_);
    }
private:
    void apply_to_layer(layer const& lay, Processor & p,
                        projection const& proj0, double scale_denom)
    {
#ifdef MAPNIK_DEBUG
        //wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif

        std::vector<std::string> const& style_names = lay.styles();

        unsigned int num_styles = style_names.size();
        if (!num_styles)
            return;

        mapnik::datasource_ptr ds = lay.datasource();
        if (!ds)
        {
            std::clog << "WARNING: No datasource for layer '" << lay.name() << "'\n";
            return;
        }

        p.start_layer_processing(lay);

        if (ds)
        {

            projection proj1(lay.srs());
            proj_transform prj_trans(proj0,proj1);

            // todo: only display raster if src and dest proj are matched
            // todo: add raster re-projection as an optional feature
            if (ds->type() == datasource::Raster && !prj_trans.equal())
            {
                std::clog << "WARNING: Map srs does not match layer srs, skipping raster layer '" << lay.name()
                    << "' as raster re-projection is not currently supported (http://trac.mapnik.org/ticket/663)\n"
                    << "map srs: '" << m_.srs() << "'\nlayer srs: '" << lay.srs() << "' \n";
                return;
            }

            box2d<double> map_ext = m_.get_buffered_extent();

            // clip buffered extent by maximum extent, if supplied
            boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
            if (maximum_extent) {
                map_ext.clip(*maximum_extent);
            }

            box2d<double> layer_ext = lay.envelope();

            // first, try to forward project map ext into layer srs
            if (prj_trans.forward(map_ext) && map_ext.intersects(layer_ext))
             {
                layer_ext.clip(map_ext);
            }
            // fallback to back projecting layer into map srs
            else if (prj_trans.backward(layer_ext) && map_ext.intersects(map_ext))
            {
                layer_ext.clip(map_ext);
                // forward project layer extent back into native projection
                if (!prj_trans.forward(layer_ext))
                    std::clog << "WARNING: layer " << lay.name()
                      << " extent " << layer_ext << " in map projection "
                      << " did not reproject properly back to layer projection\n";
            }
            else
            {
                 // if no intersection then nothing to do for layer
                 return;
            }

            query::resolution_type res(m_.width()/m_.get_current_extent().width(),
                                       m_.height()/m_.get_current_extent().height());
            query q(layer_ext,res,scale_denom); //BBOX query

            std::vector<feature_type_style*> active_styles;
            std::set<std::string> names;
            attribute_collector collector(names);
            double filt_factor = 1;
            directive_collector d_collector(&filt_factor);

            // iterate through all named styles collecting active styles and attribute names
            BOOST_FOREACH(std::string const& style_name, style_names)
            {
                boost::optional<feature_type_style const&> style=m_.find_style(style_name);
                if (!style)
                {
                    std::clog << "WARNING: style '" << style_name << "' required for layer '"
                        << lay.name() << "' does not exist.\n";
                    continue;
                }

                const std::vector<rule>& rules=(*style).get_rules();
                bool active_rules=false;

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        active_rules = true;
                        if (ds->type() == datasource::Vector)
                        {
                            collector(r);
                        }
                        // TODO - in the future rasters should be able to be filtered.
                    }
                }
                if (active_rules)
                {
                    active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
                }
            }

            // push all property names
            BOOST_FOREACH(std::string const& name, names)
            {
                q.add_property_name(name);
            }

            memory_datasource cache;
            bool cache_features = lay.cache_features() && num_styles>1?true:false;
            bool first = true;

            BOOST_FOREACH (feature_type_style * style, active_styles)
            {
                std::vector<rule*> if_rules;
                std::vector<rule*> else_rules;

                std::vector<rule> const& rules=style->get_rules();

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        if (r.has_else_filter())
                        {
                            else_rules.push_back(const_cast<rule*>(&r));
                        }
                        else
                        {
                            if_rules.push_back(const_cast<rule*>(&r));
                        }

                        if ( (ds->type() == datasource::Raster) &&
                             (ds->params().get<double>("filter_factor",0.0) == 0.0) )
                        {
                            rule::symbolizers const& symbols = r.get_symbolizers();
                            rule::symbolizers::const_iterator symIter = symbols.begin();
                            rule::symbolizers::const_iterator symEnd = symbols.end();
                            while (symIter != symEnd)
                            {
                                // if multiple raster symbolizers, last will be respected
                                // should we warn or throw?
                                boost::apply_visitor(d_collector,*symIter++);
                            }
                            q.set_filter_factor(filt_factor);
                        }
                    }
                }

                // process features
                featureset_ptr fs;
                if (first)
                {
                    if (cache_features)
                        first = false;
                    fs = ds->features(q);
                }
                else
                {
                    fs = cache.features(q);
                }

                if (fs)
                {
                    feature_ptr feature;
                    while ((feature = fs->next()))
                    {
                        bool do_else=true;

                        if (cache_features)
                        {
                            cache.push(feature);
                        }

                        BOOST_FOREACH(rule * r, if_rules )
                        {
                            expression_ptr const& expr=r->get_filter();
                            value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
                            if (result.to_bool())
                            {
                                do_else=false;
                                rule::symbolizers const& symbols = r->get_symbolizers();

                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {

                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                                if (style->get_filter_mode() == FILTER_FIRST)
                                {
                                    // Stop iterating over rules and proceed with next feature.
                                    break;
                                }
                            }
                        }
                        if (do_else)
                        {
                            BOOST_FOREACH( rule * r, else_rules )
                            {
                                rule::symbolizers const& symbols = r->get_symbolizers();
                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {
                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                            }
                        }
                    }
                }
                cache_features = false;
            }
        }

        p.end_layer_processing(lay);
    }

    Map const& m_;
    double scale_factor_;
};
}

#endif //FEATURE_STYLE_PROCESSOR_HPP
<commit_msg>refactor feature_style_processor a bit to allow passing reference of names as arg apply_to_layer. Will set up for more potential flexibility around passing pre-populated query names.<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$

#ifndef FEATURE_STYLE_PROCESSOR_HPP
#define FEATURE_STYLE_PROCESSOR_HPP

// mapnik
#include <mapnik/box2d.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/map.hpp>
#include <mapnik/attribute_collector.hpp>
#include <mapnik/expression_evaluator.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/scale_denominator.hpp>
#include <mapnik/memory_datasource.hpp>

#ifdef MAPNIK_DEBUG
//#include <mapnik/wall_clock_timer.hpp>
#endif
// boost
#include <boost/foreach.hpp>
//stl
#include <vector>

namespace mapnik
{

template <typename Processor>
class feature_style_processor
{
    /** Calls the renderer's process function,
      * \param output     Renderer
      * \param f          Feature to process
      * \param prj_trans  Projection
      * \param sym        Symbolizer object
      */
    struct symbol_dispatch : public boost::static_visitor<>
    {
        symbol_dispatch (Processor & output,
                         Feature const& f,
                         proj_transform const& prj_trans)
            : output_(output),
              f_(f),
              prj_trans_(prj_trans)  {}

        template <typename T>
        void operator () (T const& sym) const
        {
            output_.process(sym,f_,prj_trans_);
        }

        Processor & output_;
        Feature const& f_;
        proj_transform const& prj_trans_;
    };

public:

    explicit feature_style_processor(Map const& m, double scale_factor = 1.0)
        : m_(m),
          scale_factor_(scale_factor) {}

    /*!
     * @return apply renderer to all maps layers.
     */
    void apply()
    {
#ifdef MAPNIK_DEBUG
        //mapnik::wall_clock_progress_timer t(std::clog, "map rendering took: ");
#endif
        Processor & p = static_cast<Processor&>(*this);
        p.start_map_processing(m_);

        try
        {
            projection proj(m_.srs());

            start_metawriters(m_,proj);

            double scale_denom = mapnik::scale_denominator(m_,proj.is_geographic());
            scale_denom *= scale_factor_;
#ifdef MAPNIK_DEBUG
            std::clog << "scale denominator = " << scale_denom << "\n";
#endif
            BOOST_FOREACH ( layer const& lyr, m_.layers() )
            {
                if (lyr.isVisible(scale_denom))
                {
                    std::set<std::string> names;
                    apply_to_layer(lyr, p, proj, scale_denom, names);
                }
            }

            stop_metawriters(m_);
        }
        catch (proj_init_error& ex)
        {
            std::clog << "proj_init_error:" << ex.what() << "\n";
        }

        p.end_map_processing(m_);
    }

private:
    /*!
     * @return initialize metawriters for a given map and projection.
     */
    void start_metawriters(Map const& m_, projection const& proj)
    {
        Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
        Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
        for (;metaItr!=metaItrEnd; ++metaItr)
        {
            metaItr->second->set_size(m_.width(), m_.height());
            metaItr->second->set_map_srs(proj);
            metaItr->second->start(m_.metawriter_output_properties);
        }
    }
    /*!
     * @return stop metawriters that were previously initialized.
     */
    void stop_metawriters(Map const& m_)
    {
        Map::const_metawriter_iterator metaItr = m_.begin_metawriters();
        Map::const_metawriter_iterator metaItrEnd = m_.end_metawriters();
        for (;metaItr!=metaItrEnd; ++metaItr)
        {
            metaItr->second->stop();
        }
    }

    /*!
     * @return render a layer given a projection and scale
     */
    void apply_to_layer(layer const& lay, Processor & p,
                        projection const& proj0,
                        double scale_denom,
                        std::set<std::string>& names)
    {
#ifdef MAPNIK_DEBUG
        //wall_clock_progress_timer timer(clog, "end layer rendering: ");
#endif

        std::vector<std::string> const& style_names = lay.styles();

        unsigned int num_styles = style_names.size();
        if (!num_styles)
            return;

        mapnik::datasource_ptr ds = lay.datasource();
        if (!ds)
        {
            std::clog << "WARNING: No datasource for layer '" << lay.name() << "'\n";
            return;
        }

        p.start_layer_processing(lay);

        if (ds)
        {

            projection proj1(lay.srs());
            proj_transform prj_trans(proj0,proj1);

            // todo: only display raster if src and dest proj are matched
            // todo: add raster re-projection as an optional feature
            if (ds->type() == datasource::Raster && !prj_trans.equal())
            {
                std::clog << "WARNING: Map srs does not match layer srs, skipping raster layer '" << lay.name()
                    << "' as raster re-projection is not currently supported (http://trac.mapnik.org/ticket/663)\n"
                    << "map srs: '" << m_.srs() << "'\nlayer srs: '" << lay.srs() << "' \n";
                return;
            }

            box2d<double> map_ext = m_.get_buffered_extent();

            // clip buffered extent by maximum extent, if supplied
            boost::optional<box2d<double> > const& maximum_extent = m_.maximum_extent();
            if (maximum_extent) {
                map_ext.clip(*maximum_extent);
            }

            box2d<double> layer_ext = lay.envelope();

            // first, try to forward project map ext into layer srs
            if (prj_trans.forward(map_ext) && map_ext.intersects(layer_ext))
             {
                layer_ext.clip(map_ext);
            }
            // fallback to back projecting layer into map srs
            else if (prj_trans.backward(layer_ext) && map_ext.intersects(map_ext))
            {
                layer_ext.clip(map_ext);
                // forward project layer extent back into native projection
                if (!prj_trans.forward(layer_ext))
                    std::clog << "WARNING: layer " << lay.name()
                      << " extent " << layer_ext << " in map projection "
                      << " did not reproject properly back to layer projection\n";
            }
            else
            {
                 // if no intersection then nothing to do for layer
                 return;
            }

            query::resolution_type res(m_.width()/m_.get_current_extent().width(),
                                       m_.height()/m_.get_current_extent().height());
            query q(layer_ext,res,scale_denom); //BBOX query

            std::vector<feature_type_style*> active_styles;
            attribute_collector collector(names);
            double filt_factor = 1;
            directive_collector d_collector(&filt_factor);

            // iterate through all named styles collecting active styles and attribute names
            BOOST_FOREACH(std::string const& style_name, style_names)
            {
                boost::optional<feature_type_style const&> style=m_.find_style(style_name);
                if (!style)
                {
                    std::clog << "WARNING: style '" << style_name << "' required for layer '"
                        << lay.name() << "' does not exist.\n";
                    continue;
                }

                const std::vector<rule>& rules=(*style).get_rules();
                bool active_rules=false;

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        active_rules = true;
                        if (ds->type() == datasource::Vector)
                        {
                            collector(r);
                        }
                        // TODO - in the future rasters should be able to be filtered.
                    }
                }
                if (active_rules)
                {
                    active_styles.push_back(const_cast<feature_type_style*>(&(*style)));
                }
            }

            // push all property names
            BOOST_FOREACH(std::string const& name, names)
            {
                q.add_property_name(name);
            }

            memory_datasource cache;
            bool cache_features = lay.cache_features() && num_styles>1?true:false;
            bool first = true;

            BOOST_FOREACH (feature_type_style * style, active_styles)
            {
                std::vector<rule*> if_rules;
                std::vector<rule*> else_rules;

                std::vector<rule> const& rules=style->get_rules();

                BOOST_FOREACH(rule const& r, rules)
                {
                    if (r.active(scale_denom))
                    {
                        if (r.has_else_filter())
                        {
                            else_rules.push_back(const_cast<rule*>(&r));
                        }
                        else
                        {
                            if_rules.push_back(const_cast<rule*>(&r));
                        }

                        if ( (ds->type() == datasource::Raster) &&
                             (ds->params().get<double>("filter_factor",0.0) == 0.0) )
                        {
                            rule::symbolizers const& symbols = r.get_symbolizers();
                            rule::symbolizers::const_iterator symIter = symbols.begin();
                            rule::symbolizers::const_iterator symEnd = symbols.end();
                            while (symIter != symEnd)
                            {
                                // if multiple raster symbolizers, last will be respected
                                // should we warn or throw?
                                boost::apply_visitor(d_collector,*symIter++);
                            }
                            q.set_filter_factor(filt_factor);
                        }
                    }
                }

                // process features
                featureset_ptr fs;
                if (first)
                {
                    if (cache_features)
                        first = false;
                    fs = ds->features(q);
                }
                else
                {
                    fs = cache.features(q);
                }

                if (fs)
                {
                    feature_ptr feature;
                    while ((feature = fs->next()))
                    {
                        bool do_else=true;

                        if (cache_features)
                        {
                            cache.push(feature);
                        }

                        BOOST_FOREACH(rule * r, if_rules )
                        {
                            expression_ptr const& expr=r->get_filter();
                            value_type result = boost::apply_visitor(evaluate<Feature,value_type>(*feature),*expr);
                            if (result.to_bool())
                            {
                                do_else=false;
                                rule::symbolizers const& symbols = r->get_symbolizers();

                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {

                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                                if (style->get_filter_mode() == FILTER_FIRST)
                                {
                                    // Stop iterating over rules and proceed with next feature.
                                    break;
                                }
                            }
                        }
                        if (do_else)
                        {
                            BOOST_FOREACH( rule * r, else_rules )
                            {
                                rule::symbolizers const& symbols = r->get_symbolizers();
                                // if the underlying renderer is not able to process the complete set of symbolizers,
                                // process one by one.
#ifdef SVG_RENDERER
                                if(!p.process(symbols,*feature,prj_trans))
#endif
                                {
                                    BOOST_FOREACH (symbolizer const& sym, symbols)
                                    {
                                        boost::apply_visitor(symbol_dispatch(p,*feature,prj_trans),sym);
                                    }
                                }
                            }
                        }
                    }
                }
                cache_features = false;
            }
        }

        p.end_layer_processing(lay);
    }

    Map const& m_;
    double scale_factor_;
};
}

#endif //FEATURE_STYLE_PROCESSOR_HPP
<|endoftext|>