<commit_before>#include "engpar.h"
#include <PCU.h>
#include "src/engpar_sides.h"

namespace engpar {
  wgt_t getWeight(agi::Ngraph* g, int dimension, bool countGhosts) {
    wgt_t w =0;
    if (dimension==-1) {

      //calculate the total weight of the vertices
      agi::GraphVertex* vtx;
      agi::VertexIterator* vitr = g->begin();
      while ((vtx = g->iterate(vitr)))
        w+=g->weight(vtx);
      if (countGhosts)
	w+=g->numGhostVtxs();
    }
    else {
      agi::GraphEdge* edge;
      agi::EdgeIterator* eitr = g->begin(dimension);
      while ((edge = g->iterate(eitr)))
        w+=g->weight(edge);
      g->destroy(eitr);
    }
    return w;
  }

  double EnGPar_Get_Imbalance(wgt_t my_val) {
    wgt_t max,total;
    double avg;
    MPI_Datatype type = MPI_DOUBLE;
    MPI_Allreduce(&my_val,&max,1,type,MPI_MAX,PCU_Get_Comm());
    MPI_Allreduce(&my_val,&total,1,type,MPI_SUM,PCU_Get_Comm());
    avg = total*1.0/PCU_Comm_Peers();
    return max*1.0/avg;
  }

  void printImbalances(agi::Ngraph* g) {
    for (agi::etype type = -1;type<g->numEdgeTypes();type++) {
      agi::wgt_t w = getWeight(g,type);
      double imb = EnGPar_Get_Imbalance(w);
      if (!PCU_Comm_Self())
        printf("%2.4f ",imb);
    }
    if (!PCU_Comm_Self())
      printf("\n");
  }

  void printMaxMinAvgImb(agi::lid_t my_val,std::string prefix) {
    agi::gid_t in = my_val;
    agi::gid_t max,min,total;
    double avg,imb;
    MPI_Datatype type = MPI_UNSIGNED_LONG;
    MPI_Allreduce(&in,&max,1,type,MPI_MAX,PCU_Get_Comm());
    MPI_Allreduce(&in,&min,1,type,MPI_MIN,PCU_Get_Comm());
    MPI_Allreduce(&in,&total,1,type,MPI_SUM,PCU_Get_Comm());
    avg = total*1.0/PCU_Comm_Peers();
    imb = max*1.0/avg;
    if (!PCU_Comm_Self())
      printf("%s <max, min, avg, imb> = <%lu %lu %f %f>\n",
             prefix.c_str(),max,min,avg,imb);
  }
  void printMaxMinAvgImb(agi::wgt_t my_val,std::string prefix) {
    agi::wgt_t max,min,total;
    double avg,imb;
    MPI_Datatype type = MPI_DOUBLE;
    MPI_Allreduce(&my_val,&max,1,type,MPI_MAX,PCU_Get_Comm());
    MPI_Allreduce(&my_val,&min,1,type,MPI_MIN,PCU_Get_Comm());
    MPI_Allreduce(&my_val,&total,1,type,MPI_SUM,PCU_Get_Comm());
    avg = total*1.0/PCU_Comm_Peers();
    imb = max*1.0/avg;
    if (!PCU_Comm_Self())
      printf("%s <max, min, avg, imb> = <%f %f %f %f>\n",
             prefix.c_str(),max,min,avg,imb);
  }

  void evaluatePartition(agi::Ngraph* g,std::string) {
    agi::wgt_t* my_vals = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* min = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* max = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* total = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* avg = new agi::wgt_t[2+g->numEdgeTypes()+3];

    //Disconnected comp
    my_vals[0] = 0;

    //Neighbors & Part Boundary
    DiffusiveInput* in = static_cast<DiffusiveInput*>(createDiffusiveInput(g,0));
    Sides* sides = makeSides(in);
    my_vals[1] = sides->size();
    my_vals[2] = sides->total();
    delete in;

    //Vertex Imbalance
    my_vals[3] = getWeight(g,-1);
    my_vals[4] = getWeight(g,-1,true);

    //Edge type imbalance
    for (agi::etype t = 0;t<g->numEdgeTypes();t++) {
      my_vals[t+5] = getWeight(g,t);
    }

    //Empty parts
    int empty = my_vals[3]==0;

    MPI_Reduce(my_vals,max,5+g->numEdgeTypes(),MPI_DOUBLE,MPI_MAX,0,PCU_Get_Comm());
    MPI_Reduce(my_vals,min,5+g->numEdgeTypes(),MPI_DOUBLE,MPI_MIN,0,PCU_Get_Comm());
    MPI_Reduce(my_vals,total,5+g->numEdgeTypes(),MPI_DOUBLE,MPI_SUM,0,PCU_Get_Comm());
    empty = PCU_Add_Int(empty);

    if (!PCU_Comm_Self()) {
      for (int i=0;i<5+g->numEdgeTypes();i++) {
        avg[i] = total[i]/PCU_Comm_Peers();
      }
      printf("ENGPAR STATUS: Empty Parts: %d\n"
             "ENGPAR STATUS: Disconnected Components: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Neighbors: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Edge Cut: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Local Vertex Imbalance: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Total Vertex Imbalance: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n",
             empty,max[0],min[0],avg[0],total[0]/avg[0],max[1],min[1],avg[1],total[1]/avg[1],
             max[2],min[2],avg[2],total[2]/avg[2],max[3],min[3],avg[3],total[3]/avg[3],
             max[4],min[4],avg[4],total[4]/avg[4]);
      for (int i=0;i<g->numEdgeTypes();i++) {
        char edge_name[15];
        sprintf(edge_name,"Edges type %d",i);
        printf("ENGPAR STATUS: %s: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n",edge_name,
               max[5+i],min[5+i],avg[5+i],total[5+i]/avg[5+i]);
      }
    }
  }
}
<commit_msg>Plug leaks introduced in last commit<commit_after>#include "engpar.h"
#include <PCU.h>
#include "src/engpar_sides.h"

namespace engpar {
  wgt_t getWeight(agi::Ngraph* g, int dimension, bool countGhosts) {
    wgt_t w =0;
    if (dimension==-1) {

      //calculate the total weight of the vertices
      agi::GraphVertex* vtx;
      agi::VertexIterator* vitr = g->begin();
      while ((vtx = g->iterate(vitr)))
        w+=g->weight(vtx);
      if (countGhosts)
	w+=g->numGhostVtxs();
    }
    else {
      agi::GraphEdge* edge;
      agi::EdgeIterator* eitr = g->begin(dimension);
      while ((edge = g->iterate(eitr)))
        w+=g->weight(edge);
      g->destroy(eitr);
    }
    return w;
  }

  double EnGPar_Get_Imbalance(wgt_t my_val) {
    wgt_t max,total;
    double avg;
    MPI_Datatype type = MPI_DOUBLE;
    MPI_Allreduce(&my_val,&max,1,type,MPI_MAX,PCU_Get_Comm());
    MPI_Allreduce(&my_val,&total,1,type,MPI_SUM,PCU_Get_Comm());
    avg = total*1.0/PCU_Comm_Peers();
    return max*1.0/avg;
  }

  void printImbalances(agi::Ngraph* g) {
    for (agi::etype type = -1;type<g->numEdgeTypes();type++) {
      agi::wgt_t w = getWeight(g,type);
      double imb = EnGPar_Get_Imbalance(w);
      if (!PCU_Comm_Self())
        printf("%2.4f ",imb);
    }
    if (!PCU_Comm_Self())
      printf("\n");
  }

  void printMaxMinAvgImb(agi::lid_t my_val,std::string prefix) {
    agi::gid_t in = my_val;
    agi::gid_t max,min,total;
    double avg,imb;
    MPI_Datatype type = MPI_UNSIGNED_LONG;
    MPI_Allreduce(&in,&max,1,type,MPI_MAX,PCU_Get_Comm());
    MPI_Allreduce(&in,&min,1,type,MPI_MIN,PCU_Get_Comm());
    MPI_Allreduce(&in,&total,1,type,MPI_SUM,PCU_Get_Comm());
    avg = total*1.0/PCU_Comm_Peers();
    imb = max*1.0/avg;
    if (!PCU_Comm_Self())
      printf("%s <max, min, avg, imb> = <%lu %lu %f %f>\n",
             prefix.c_str(),max,min,avg,imb);
  }
  void printMaxMinAvgImb(agi::wgt_t my_val,std::string prefix) {
    agi::wgt_t max,min,total;
    double avg,imb;
    MPI_Datatype type = MPI_DOUBLE;
    MPI_Allreduce(&my_val,&max,1,type,MPI_MAX,PCU_Get_Comm());
    MPI_Allreduce(&my_val,&min,1,type,MPI_MIN,PCU_Get_Comm());
    MPI_Allreduce(&my_val,&total,1,type,MPI_SUM,PCU_Get_Comm());
    avg = total*1.0/PCU_Comm_Peers();
    imb = max*1.0/avg;
    if (!PCU_Comm_Self())
      printf("%s <max, min, avg, imb> = <%f %f %f %f>\n",
             prefix.c_str(),max,min,avg,imb);
  }

  void evaluatePartition(agi::Ngraph* g,std::string) {
    agi::wgt_t* my_vals = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* min = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* max = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* total = new agi::wgt_t[2+g->numEdgeTypes()+3];
    agi::wgt_t* avg = new agi::wgt_t[2+g->numEdgeTypes()+3];

    //Disconnected comp
    my_vals[0] = 0;

    //Neighbors & Part Boundary
    DiffusiveInput* in = static_cast<DiffusiveInput*>(createDiffusiveInput(g,0));
    Sides* sides = makeSides(in);
    my_vals[1] = sides->size();
    my_vals[2] = sides->total();
    delete in;
    delete sides;

    //Vertex Imbalance
    my_vals[3] = getWeight(g,-1);
    my_vals[4] = getWeight(g,-1,true);

    //Edge type imbalance
    for (agi::etype t = 0;t<g->numEdgeTypes();t++) {
      my_vals[t+5] = getWeight(g,t);
    }

    //Empty parts
    int empty = my_vals[3]==0;

    MPI_Reduce(my_vals,max,5+g->numEdgeTypes(),MPI_DOUBLE,MPI_MAX,0,PCU_Get_Comm());
    MPI_Reduce(my_vals,min,5+g->numEdgeTypes(),MPI_DOUBLE,MPI_MIN,0,PCU_Get_Comm());
    MPI_Reduce(my_vals,total,5+g->numEdgeTypes(),MPI_DOUBLE,MPI_SUM,0,PCU_Get_Comm());
    empty = PCU_Add_Int(empty);
    delete [] my_vals;
    if (!PCU_Comm_Self()) {
      for (int i=0;i<5+g->numEdgeTypes();i++) {
        avg[i] = total[i]/PCU_Comm_Peers();
      }
      printf("ENGPAR STATUS: Empty Parts: %d\n"
             "ENGPAR STATUS: Disconnected Components: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Neighbors: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Edge Cut: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Local Vertex Imbalance: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n"
             "ENGPAR STATUS: Total Vertex Imbalance: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n",
             empty,max[0],min[0],avg[0],total[0]/avg[0],max[1],min[1],avg[1],total[1]/avg[1],
             max[2],min[2],avg[2],total[2]/avg[2],max[3],min[3],avg[3],total[3]/avg[3],
             max[4],min[4],avg[4],total[4]/avg[4]);
      for (int i=0;i<g->numEdgeTypes();i++) {
        char edge_name[15];
        sprintf(edge_name,"Edges type %d",i);
        printf("ENGPAR STATUS: %s: <min,max,avg,imb> %.3f %.3f %.3f %.3f\n",edge_name,
               max[5+i],min[5+i],avg[5+i],total[5+i]/avg[5+i]);
      }
    }

  delete [] max;
  delete [] min;
  delete [] total;
  delete [] avg;
  }
}
<|endoftext|>


<commit_before>// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#pragma once

#include "../ForwardDeclarations.hpp"
#include "JsonNode.hpp"

namespace ArduinoJson {
namespace Internals {

class JsonNodeWrapper {
  friend class JsonValue;

 public:
  JsonNodeWrapper() : _node(0) {}

  explicit JsonNodeWrapper(JsonNode *node) : _node(node) {}

 protected:
  void duplicate(const JsonNodeWrapper &other) {
    if (!_node) {
      _node = other._node;
    } else {
      _node->duplicate(other._node);
    }
  }

  JsonNode *_node;
};
}
}
<commit_msg>Cleaned JsonNodeWrapper<commit_after>// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson

#pragma once

#include "JsonNode.hpp"

namespace ArduinoJson {
namespace Internals {

class JsonNodeWrapper {
 protected:
  JsonNodeWrapper() : _node(0) {}

  explicit JsonNodeWrapper(JsonNode *node) : _node(node) {}

  void duplicate(const JsonNodeWrapper &other) {
    if (!_node) {
      _node = other._node;
    } else {
      _node->duplicate(other._node);
    }
  }

  JsonNode *_node;
};
}
}
<|endoftext|>


<commit_before>//	Copyright 2017 Adam Smith
//	Licensed under the Apache License, Version 2.0 (the "License");
//	you may not use this file except in compliance with the License.
//	You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
//	Unless required by applicable law or agreed to in writing, software
//	distributed under the License is distributed on an "AS IS" BASIS,
//	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//	See the License for the specific language governing permissions and
//	limitations under the License.

#ifndef ASMITH_REFLECTION_INSTANCE_HPP
#define ASMITH_REFLECTION_INSTANCE_HPP

#include "reflection_class.hpp"
#include "reflection_constructor.hpp"
#include "reflection_destructor.hpp"
#include "reflection_function.hpp"
#include "reflection_variable.hpp"
#include "reflection_modifier.hpp"

namespace asmith {
	class reflection_instance {
	private:
		const reflection_class* mClass;
		void* mData;

		reflection_instance& operator=(reflection_instance&&) = delete;
		reflection_instance& operator=(const reflection_instance&) = delete;
	public:
		reflection_instance();
		reflection_instance(reflection_instance&&);
		reflection_instance(const reflection_instance&);
		~reflection_instance();

		reflection_instance call_unsafe(const char*, const void*);
		const reflection_class& get_class() const;

		template<class ...PARAMS>
		reflection_instance(const reflection_class& aClass, PARAMS... aParams) :
			mClass(&aClass),
			mData(operator new(aClass.get_size()))
		{
			//! \todo Check argument types
			const size_t s = aClass.get_constructor_count();
			for(size_t i = 0; i < s; ++i) {
				const reflection_constructor& con = aClass.get_constructor(i);
				if(con.get_parameter_count() == sizeof...(PARAMS)) {
					con.call(mData, aParams...);
					return;
				}
			}
			throw std::runtime_error("asmith::reflection_instance : No constructor with parameter count");
		}

		template<class R, class ...PARAMS>
		R call(const char* aName, PARAMS... aParams) {
			//! \todo Handle overloaded functions
			return mClass->get_function(aName).call<R, int, PARAMS...>(*reinterpret_cast<int*>(mData));
		}

		template<class T>
		T get_variable(const char* aName) {
			return mClass->get_variable(aName).get<T>();
		}

		template<class T>
		void set_variable(const char* aName, T aValue) {
			return mClass->get_variable(aName).set<T>(aValue);
		}
	};
}

#endif<commit_msg>Added conversion<commit_after>//	Copyright 2017 Adam Smith
//	Licensed under the Apache License, Version 2.0 (the "License");
//	you may not use this file except in compliance with the License.
//	You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
//	Unless required by applicable law or agreed to in writing, software
//	distributed under the License is distributed on an "AS IS" BASIS,
//	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//	See the License for the specific language governing permissions and
//	limitations under the License.

#ifndef ASMITH_REFLECTION_INSTANCE_HPP
#define ASMITH_REFLECTION_INSTANCE_HPP

#include "reflection_class.hpp"
#include "reflection_constructor.hpp"
#include "reflection_destructor.hpp"
#include "reflection_function.hpp"
#include "reflection_variable.hpp"
#include "reflection_modifier.hpp"

namespace asmith {
	class reflection_instance {
	private:
		const reflection_class* mClass;
		void* mData;

		reflection_instance& operator=(reflection_instance&&) = delete;
		reflection_instance& operator=(const reflection_instance&) = delete;
	public:
		reflection_instance();
		reflection_instance(reflection_instance&&);
		reflection_instance(const reflection_instance&);
		~reflection_instance();

		reflection_instance call_unsafe(const char*, const void*);
		const reflection_class& get_class() const;

		template<class ...PARAMS>
		reflection_instance(const reflection_class& aClass, PARAMS... aParams) :
			mClass(&aClass),
			mData(operator new(aClass.get_size()))
		{
			//! \todo Check argument types
			const size_t s = aClass.get_constructor_count();
			for(size_t i = 0; i < s; ++i) {
				const reflection_constructor& con = aClass.get_constructor(i);
				if(con.get_parameter_count() == sizeof...(PARAMS)) {
					con.call(mData, aParams...);
					return;
				}
			}
			throw std::runtime_error("asmith::reflection_instance : No constructor with parameter count");
		}

		template<class R, class ...PARAMS>
		R call(const char* aName, PARAMS... aParams) {
			//! \todo Handle overloaded functions
			return mClass->get_function(aName).call<R, int, PARAMS...>(*reinterpret_cast<int*>(mData));
		}

		template<class T>
		T get_variable(const char* aName) {
			return mClass->get_variable(aName).get<T>();
		}

		template<class T>
		void set_variable(const char* aName, T aValue) {
			return mClass->get_variable(aName).set<T>(aValue);
		}

		template<class T>
		T& as() {
			if(strcmp(mClass->get_name(), reflect<T>().get_name()) != 0) throw std::runtime_error("asmith::reflection_instance::as : Type mismatch");
			return *reinterpret_cast<T*>(mData);
		}

		template<class T>
		const T& as() const {
			if(strcmp(mClass->get_name(), reflect<T>().get_name()) != 0) throw std::runtime_error("asmith::reflection_instance::as : Type mismatch");
			return *reinterpret_cast<const T*>(mData);
		}
	};
}

#endif<|endoftext|>


<commit_before>// See the file  in the main distribution directory for copyright.

#include <zeek/zeek-config.h>

#include "TestimonySource.h"
#include <zeek/iosource/Packet.h>
#include <zeek/iosource/BPF_Program.h>

#include <unistd.h>

#include <zeek/Event.h>

using namespace ZEEK_IOSOURCE_NS::testimony;

TestimonySource::~TestimonySource()
	{
	Close();
	}

void TestimonySource::Open()
	{
	OpenLive();
	}

void TestimonySource::Close()
	{
	//temporary_queue_writer will be deleted automatically by thread manager
	testimony_close(td);
	Closed();
	}

void TestimonySource::OpenLive()
	{
	int res;
	const char *fanout_str = getenv("TESTIMONY_FANOUT_ID");
	uint32_t fanout_id;

	res = testimony_connect(&td, props.path.c_str());
	if ( res < 0 )
		{
		Error("testimony_connect: " + std::string(strerror(-res)));
		return;
		}

	if ( fanout_str )
		{
		sscanf(fanout_str, "%u", &fanout_id);
		testimony_conn(td)->fanout_index = fanout_id;
		}

	res = testimony_init(td);
	if ( res < 0 )
		{
		Error("testimony_init: " + std::string(testimony_error(td)) + strerror(-res));
		return;
		}

	testimony_iter_init(&td_iter);

	props.selectable_fd = -1;

	props.link_type = DLT_EN10MB;
	props.is_live = true;

	temporary_queue_writer = new TemporaryQueueWriter();
	temporary_queue_writer->SetTestimonySource([this] () { this->AddPacketsToTemporaryQueue(); });
	temporary_queue_writer->SetStoppingProcess([this] () { this->running = false; } );
	temporary_queue_writer->StartThread();

	Opened(props);
	}

void TestimonySource::AddPacketsToTemporaryQueue()
	{
	while (running)
		{

		const tpacket_block_desc *block = NULL;
		const tpacket3_hdr *packet;

		int res = testimony_get_block(td, 0, &block);
		if ( res == 0 && !block ) {
			if (!running) {
				return;
			}

			// Timeout
			continue;
		}

		if ( res < 0 )
			{
			Error("testimony_get_block:" + std::string(testimony_error(td)) + strerror(-res));
			running = false;
			Close();
			}

		int cnt = 0;

		testimony_iter_reset(td_iter, block);
		queue_access_mutex.lock();
		while ( (packet = testimony_iter_next(td_iter)) )
			{
			// Queue the packet
			char *data = new char[packet->tp_len + packet->tp_mac]; // 0 bytes alloc`d inside block of size 144
			memcpy(data, packet, packet->tp_len + packet->tp_mac);

			temp_packets.emplace((tpacket3_hdr *) data);

			++stats.received;
			++cnt;
			stats.bytes_received += packet->tp_len;
			delete[] data;  //asd
			}
		queue_access_mutex.unlock();
		testimony_return_block(td, block);
		}
	Error("testimony loop stopped:");
	}

bool TestimonySource::ExtractNextPacket(Packet* pkt)
	{
	if ( ! packets.empty() )
		{
		curr_packet = packets.front();
		packets.pop();

		curr_timeval.tv_sec = curr_packet->tp_sec;
		curr_timeval.tv_usec = curr_packet->tp_nsec / 1000;
		pkt->Init(props.link_type, &curr_timeval, curr_packet->tp_snaplen, curr_packet->tp_len, (const u_char *) curr_packet + curr_packet->tp_mac);

		return true;
		}
	else
		{
			queue_access_mutex.lock();
			if(!temp_packets.empty())
				{
				std::swap(packets, temp_packets);
				queue_access_mutex.unlock();
				return ExtractNextPacket(pkt);
				}
			queue_access_mutex.unlock();
		}
		return false;
	}

void TestimonySource::DoneWithPacket()
	{
	if ( curr_packet )
		{
		delete curr_packet; 				//mismatched free/delate/delate[]
		curr_packet = NULL;
		}
	}

bool TestimonySource::PrecompileFilter(int index, const std::string& filter)
	{
	// Nothing to do. Packet filters are configured on
	// testimony daemon side
	return true;
	}

bool TestimonySource::SetFilter(int index)
	{
	return true;
	}

void TestimonySource::Statistics(Stats* s)
	{
	queue_access_mutex.lock();
	s->received = stats.received;
	s->bytes_received = stats.bytes_received;

	// TODO: get this information from the daemon
	s->link = stats.received;
	s->dropped = 0;
	queue_access_mutex.unlock();
	}

ZEEK_IOSOURCE_NS::PktSrc* TestimonySource::Instantiate(const std::string& path, bool is_live)
	{
	return new TestimonySource(path, is_live);
	}
<commit_msg>Added fix for mutexes<commit_after>// See the file  in the main distribution directory for copyright.

#include <zeek/zeek-config.h>

#include "TestimonySource.h"
#include <zeek/iosource/Packet.h>
#include <zeek/iosource/BPF_Program.h>

#include <unistd.h>

#include <zeek/Event.h>

using namespace ZEEK_IOSOURCE_NS::testimony;

TestimonySource::~TestimonySource()
	{
	Close();
	}

void TestimonySource::Open()
	{
	OpenLive();
	}

void TestimonySource::Close()
	{
	//temporary_queue_writer will be deleted automatically by thread manager
	testimony_close(td);
	Closed();
	}

void TestimonySource::OpenLive()
	{
	int res;
	const char *fanout_str = getenv("TESTIMONY_FANOUT_ID");
	uint32_t fanout_id;

	res = testimony_connect(&td, props.path.c_str());
	if ( res < 0 )
		{
		Error("testimony_connect: " + std::string(strerror(-res)));
		return;
		}

	if ( fanout_str )
		{
		sscanf(fanout_str, "%u", &fanout_id);
		testimony_conn(td)->fanout_index = fanout_id;
		}

	res = testimony_init(td);
	if ( res < 0 )
		{
		Error("testimony_init: " + std::string(testimony_error(td)) + strerror(-res));
		return;
		}

	testimony_iter_init(&td_iter);

	props.selectable_fd = -1;

	props.link_type = DLT_EN10MB;
	props.is_live = true;

	temporary_queue_writer = new TemporaryQueueWriter();
	temporary_queue_writer->SetTestimonySource([this] () { this->AddPacketsToTemporaryQueue(); });
	temporary_queue_writer->SetStoppingProcess([this] () { this->running = false; } );
	temporary_queue_writer->StartThread();

	Opened(props);
	}

void TestimonySource::AddPacketsToTemporaryQueue()
	{
	while (running)
		{

		const tpacket_block_desc *block = NULL;
		const tpacket3_hdr *packet;

		int res = testimony_get_block(td, 0, &block);
		if ( res == 0 && !block ) {
			if (!running) {
				return;
			}

			// Timeout
			continue;
		}

		if ( res < 0 )
			{
			Error("testimony_get_block:" + std::string(testimony_error(td)) + strerror(-res));
			running = false;
			Close();
			}

		int cnt = 0;

		testimony_iter_reset(td_iter, block);
		queue_access_mutex.lock();
		while ( (packet = testimony_iter_next(td_iter)) )
			{
			// Queue the packet
			char *data = new char[packet->tp_len + packet->tp_mac]; // 0 bytes alloc`d inside block of size 144
			memcpy(data, packet, packet->tp_len + packet->tp_mac);

			temp_packets.emplace((tpacket3_hdr *) data);

			++stats.received;
			++cnt;
			stats.bytes_received += packet->tp_len;
			delete[] data;  //asd
			}
		queue_access_mutex.unlock();
		testimony_return_block(td, block);
		}
	Error("testimony loop stopped:");
	}

bool TestimonySource::ExtractNextPacket(Packet* pkt)
	{
	if ( ! packets.empty() )
		{
		curr_packet = packets.front();
		packets.pop();

		curr_timeval.tv_sec = curr_packet->tp_sec;
		curr_timeval.tv_usec = curr_packet->tp_nsec / 1000;
		pkt->Init(props.link_type, &curr_timeval, curr_packet->tp_snaplen, curr_packet->tp_len, (const u_char *) curr_packet + curr_packet->tp_mac);

		return true;
		}
	else
		{
			queue_access_mutex.lock();
			if(!temp_packets.empty())
				{
				std::swap(packets, temp_packets);
				queue_access_mutex.unlock();
				return false;
				}
			queue_access_mutex.unlock();
		}
		return false;
	}

void TestimonySource::DoneWithPacket()
	{
	if ( curr_packet != NULL )
		{
		//delete curr_packet; 				//mismatched free/delate/delate[]
		curr_packet = NULL;
		}
	}

bool TestimonySource::PrecompileFilter(int index, const std::string& filter)
	{
	// Nothing to do. Packet filters are configured on
	// testimony daemon side
	return true;
	}

bool TestimonySource::SetFilter(int index)
	{
	return true;
	}

void TestimonySource::Statistics(Stats* s)
	{
	queue_access_mutex.lock();
	s->received = stats.received;
	s->bytes_received = stats.bytes_received;

	// TODO: get this information from the daemon
	s->link = stats.received;
	s->dropped = 0;
	queue_access_mutex.unlock();
	}

ZEEK_IOSOURCE_NS::PktSrc* TestimonySource::Instantiate(const std::string& path, bool is_live)
	{
	return new TestimonySource(path, is_live);
	}
<|endoftext|>


<commit_before>/*
    Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
      @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>

    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 program 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 General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "textchannelapprover.h"
#include <QMenu>
#include <KNotification>
#include <KStatusNotifierItem>
#include <KLocalizedString>

#include <TelepathyQt/ReceivedMessage>
#include <TelepathyQt/AvatarData>
#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingContacts>

TextChannelApprover::TextChannelApprover(const Tp::TextChannelPtr & channel, QObject *parent)
    : ChannelApprover(parent), m_notifierItem(getNotifierItem())
{
    Q_FOREACH(const Tp::ReceivedMessage & msg, channel->messageQueue()) {
        onMessageReceived(msg);
    }

    connect(channel.data(), SIGNAL(messageReceived(Tp::ReceivedMessage)),
            SLOT(onMessageReceived(Tp::ReceivedMessage)));
    connect(m_notifierItem.data(), SIGNAL(activateRequested(bool,QPoint)),
            SIGNAL(channelAccepted()));

    updateNotifierItemTooltip();
}

TextChannelApprover::~TextChannelApprover()
{
    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
        m_notification.data()->deleteLater();
    }
}

void TextChannelApprover::onMessageReceived(const Tp::ReceivedMessage & msg)
{
    if (msg.isDeliveryReport()) {
        return;
    }
    if (msg.deliveryDetails().status() == Tp::DeliveryStatusRead) {
        // The message is already read; nothing to notify about.
        return;
    }

    if (!m_notification) {
        m_notification = new KNotification("new_text_message", 0, KNotification::Persistent);
        m_notification.data()->setComponentName(QStringLiteral("ktelepathy"));

        Tp::ContactPtr sender = msg.sender();
        if (sender) {
            m_notification.data()->setTitle(sender->alias());

            QPixmap pixmap;
            if (pixmap.load(sender->avatarData().fileName)) {
                m_notification.data()->setPixmap(pixmap);
            }
        } else {
            m_notification.data()->setTitle(i18n("Incoming message"));
        }

        m_notification.data()->setActions(QStringList() << i18n("Respond"));
        connect(m_notification.data(), SIGNAL(action1Activated()), SIGNAL(channelAccepted()));
    }

    m_notifierItem.data()->contextMenu()->clear(); //calling clear removes the pointless title
    m_notifierItem.data()->contextMenu()->addAction(i18n("Accept"), this, SIGNAL(channelAccepted()));
    m_notifierItem.data()->contextMenu()->addAction(i18n("Close"), this, SIGNAL(channelRejected()));

    m_notification.data()->setText(msg.text().simplified());
    m_notification.data()->sendEvent();
}

Q_GLOBAL_STATIC(QWeakPointer<KStatusNotifierItem>, s_notifierItem)

//static
QSharedPointer<KStatusNotifierItem> TextChannelApprover::getNotifierItem()
{
    QSharedPointer<KStatusNotifierItem> notifierItem = s_notifierItem->toStrongRef();
    if (!notifierItem) {
        notifierItem = QSharedPointer<KStatusNotifierItem>(new KStatusNotifierItem);
        notifierItem->setCategory(KStatusNotifierItem::Communications);
        notifierItem->setStatus(KStatusNotifierItem::NeedsAttention);
        notifierItem->setIconByName(QLatin1String("mail-unread"));
        notifierItem->setAttentionIconByName(QLatin1String("mail-unread-new"));
        notifierItem->setStandardActionsEnabled(false);
        notifierItem->setProperty("approver_new_channels_count", 0U);

        *s_notifierItem = notifierItem;
    }

    return notifierItem;
}

void TextChannelApprover::updateNotifierItemTooltip()
{
    QVariant channelsCount = m_notifierItem->property("approver_new_channels_count");
    channelsCount = QVariant(channelsCount.toUInt() + 1);
    m_notifierItem->setProperty("approver_new_channels_count", channelsCount);

    m_notifierItem->setToolTip(QLatin1String("mail-unread-new"),
                               i18np("You have 1 incoming conversation",
                                     "You have %1 incoming conversations",
                                     channelsCount.toUInt()),
                               QString());
}

#include "textchannelapprover.moc"
<commit_msg>TextChannelApprover: Don't show notification for silent messages<commit_after>/*
    Copyright (C) 2010 Collabora Ltd. <info@collabora.co.uk>
      @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>

    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 program 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 General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "textchannelapprover.h"
#include <QMenu>
#include <KNotification>
#include <KStatusNotifierItem>
#include <KLocalizedString>

#include <TelepathyQt/ReceivedMessage>
#include <TelepathyQt/AvatarData>
#include <TelepathyQt/ContactManager>
#include <TelepathyQt/PendingContacts>

TextChannelApprover::TextChannelApprover(const Tp::TextChannelPtr & channel, QObject *parent)
    : ChannelApprover(parent), m_notifierItem(getNotifierItem())
{
    Q_FOREACH(const Tp::ReceivedMessage & msg, channel->messageQueue()) {
        onMessageReceived(msg);
    }

    connect(channel.data(), SIGNAL(messageReceived(Tp::ReceivedMessage)),
            SLOT(onMessageReceived(Tp::ReceivedMessage)));
    connect(m_notifierItem.data(), SIGNAL(activateRequested(bool,QPoint)),
            SIGNAL(channelAccepted()));

    updateNotifierItemTooltip();
}

TextChannelApprover::~TextChannelApprover()
{
    //destroy the notification
    if (m_notification) {
        m_notification.data()->close();
        m_notification.data()->deleteLater();
    }
}

void TextChannelApprover::onMessageReceived(const Tp::ReceivedMessage & msg)
{
    if (msg.isDeliveryReport()) {
        return;
    }
    if (msg.deliveryDetails().status() == Tp::DeliveryStatusRead) {
        // The message is already read; nothing to notify about.
        return;
    }
    if (msg.isSilent()) {
        return;
    }

    if (!m_notification) {
        m_notification = new KNotification("new_text_message", 0, KNotification::Persistent);
        m_notification.data()->setComponentName(QStringLiteral("ktelepathy"));

        Tp::ContactPtr sender = msg.sender();
        if (sender) {
            m_notification.data()->setTitle(sender->alias());

            QPixmap pixmap;
            if (pixmap.load(sender->avatarData().fileName)) {
                m_notification.data()->setPixmap(pixmap);
            }
        } else {
            m_notification.data()->setTitle(i18n("Incoming message"));
        }

        m_notification.data()->setActions(QStringList() << i18n("Respond"));
        connect(m_notification.data(), SIGNAL(action1Activated()), SIGNAL(channelAccepted()));
    }

    m_notifierItem.data()->contextMenu()->clear(); //calling clear removes the pointless title
    m_notifierItem.data()->contextMenu()->addAction(i18n("Accept"), this, SIGNAL(channelAccepted()));
    m_notifierItem.data()->contextMenu()->addAction(i18n("Close"), this, SIGNAL(channelRejected()));

    m_notification.data()->setText(msg.text().simplified());
    m_notification.data()->sendEvent();
}

Q_GLOBAL_STATIC(QWeakPointer<KStatusNotifierItem>, s_notifierItem)

//static
QSharedPointer<KStatusNotifierItem> TextChannelApprover::getNotifierItem()
{
    QSharedPointer<KStatusNotifierItem> notifierItem = s_notifierItem->toStrongRef();
    if (!notifierItem) {
        notifierItem = QSharedPointer<KStatusNotifierItem>(new KStatusNotifierItem);
        notifierItem->setCategory(KStatusNotifierItem::Communications);
        notifierItem->setStatus(KStatusNotifierItem::NeedsAttention);
        notifierItem->setIconByName(QLatin1String("mail-unread"));
        notifierItem->setAttentionIconByName(QLatin1String("mail-unread-new"));
        notifierItem->setStandardActionsEnabled(false);
        notifierItem->setProperty("approver_new_channels_count", 0U);

        *s_notifierItem = notifierItem;
    }

    return notifierItem;
}

void TextChannelApprover::updateNotifierItemTooltip()
{
    QVariant channelsCount = m_notifierItem->property("approver_new_channels_count");
    channelsCount = QVariant(channelsCount.toUInt() + 1);
    m_notifierItem->setProperty("approver_new_channels_count", channelsCount);

    m_notifierItem->setToolTip(QLatin1String("mail-unread-new"),
                               i18np("You have 1 incoming conversation",
                                     "You have %1 incoming conversations",
                                     channelsCount.toUInt()),
                               QString());
}

#include "textchannelapprover.moc"
<|endoftext|>


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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef _itkVectorMeanDiffusionImageFilter_HXX__
#define _itkVectorMeanDiffusionImageFilter_HXX__

#include "itkVectorMeanDiffusionImageFilter.h"

#include "itkNeighborhoodIterator.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
#include "itkProgressReporter.h"

//#include "itkCastImageFilter.h"
//#include "itkImageFileWriter.h"

namespace itk
{

	/**
	 * *********************** Constructor **************************
	 */

	template < class TInputImage, class TGrayValueImage >
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::VectorMeanDiffusionImageFilter()
	{
		/** Initialise things for the filter. */
		this->m_NumberOfIterations = 0;
		this->m_Radius.Fill(1);
		this->m_RescaleFilter = 0;
		this->m_GrayValueImage = 0;
		this->m_Cx = 0;

	} // end Constructor

	/**
	 * *************** GenerateInputRequestedRegion *****************
	 */

	template < class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError)
	{
		// call the superclass' implementation of this method
		Superclass::GenerateInputRequestedRegion();

		// get pointers to the input and output
		typename Superclass::InputImagePointer inputPtr =
			const_cast< TInputImage * >( this->GetInput() );
		typename Superclass::OutputImagePointer outputPtr = this->GetOutput();

		if ( !inputPtr || !outputPtr )
    {
			return;
    }

		// get a copy of the input requested region (should equal the output
		// requested region)
		typename TInputImage::RegionType inputRequestedRegion;
		inputRequestedRegion = inputPtr->GetRequestedRegion();

		// pad the input requested region by the operator radius
		inputRequestedRegion.PadByRadius( this->m_Radius );

		// crop the input requested region at the input's largest possible region
		if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
    {
			inputPtr->SetRequestedRegion( inputRequestedRegion );
			return;
    }
		else
    {
			// Couldn't crop the region (requested region is outside the largest
			// possible region).  Throw an exception.

			// store what we tried to request (prior to trying to crop)
			inputPtr->SetRequestedRegion( inputRequestedRegion );

			// build an exception
			InvalidRequestedRegionError e(__FILE__, __LINE__);
			OStringStream msg;
			msg << static_cast<const char *>(this->GetNameOfClass())
        << "::GenerateInputRequestedRegion()";
			e.SetLocation(msg.str().c_str());
			e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
			e.SetDataObject(inputPtr);
			throw e;
    }

	} // end GenerateInputRequestedRegion

	/**
	 * ********************** GenerateData **************************
	 */

	template < class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::GenerateData(void)
	{
		/** Create feature image. */
		this->FilterGrayValueImage();

		/** Declare things. */
		unsigned int i, j;
		ZeroFluxNeumannBoundaryCondition< InputImageType >			nbc;
		ZeroFluxNeumannBoundaryCondition< DoubleImageType >			nbc2;
		NeighborhoodIterator< InputImageType >									nit;
		NeighborhoodIterator< DoubleImageType >									nit2;
		VectorRealType sum;

		/** Allocate output. */
		typename InputImageType::ConstPointer	input(	this->GetInput() );
		typename InputImageType::Pointer			output( this->GetOutput() );
		typename InputImageType::Pointer			outputtmp = InputImageType::New();

		output->SetRegions( input->GetLargestPossibleRegion() );
		output->Allocate();

		/** Allocate a temporary output image. */
		outputtmp->SetSpacing( input->GetSpacing() );
		outputtmp->SetOrigin( input->GetOrigin() );
		outputtmp->SetRegions( input->GetLargestPossibleRegion() );
		outputtmp->Allocate();

		// support progress methods/callbacks
		//ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );

		/** Copy input to output. */
		ImageRegionConstIterator< InputImageType >	in_it(
			input, input->GetLargestPossibleRegion() );
		ImageRegionIterator< InputImageType >				out_it(
			output, input->GetLargestPossibleRegion() );
		in_it.GoToBegin();
		out_it.GoToBegin();
		while ( !in_it.IsAtEnd() )
		{
			out_it.Set( in_it.Get() );
			++in_it;
			++out_it;
		}

		/** Setup neighborhood iterator for the output deformation image. */
		nit = NeighborhoodIterator< InputImageType >(
			this->m_Radius, output, output->GetLargestPossibleRegion() );
		unsigned int neighborhoodSize = nit.Size();
		nit.OverrideBoundaryCondition( &nbc );

		/** Setup neighborhood iterator for the "stiffness coefficient" image. */
		nit2 = NeighborhoodIterator< DoubleImageType >(
			this->m_Radius, this->m_Cx, this->m_Cx->GetLargestPossibleRegion() );
		nit2.OverrideBoundaryCondition( &nbc2 );

		/** Setup iterator over outputtmp. */
		ImageRegionIterator< InputImageType >				oit(
			outputtmp, input->GetLargestPossibleRegion() );

		/** Initialize c and ci. */
		double c = 0.0;
		double ci = 0.0;

		/** Loop over the number of iterations. */
		for ( unsigned int k = 0; k < this->GetNumberOfIterations(); k++ )
		{
			nit.GoToBegin();
			nit2.GoToBegin();
			oit.GoToBegin();

			/** The actual work. */
			while ( !nit.IsAtEnd() )
			{
				/** Initialize the sum to 0. */
				for ( j = 0; j < InputImageDimension; j++ )
				{
					sum[ j ] = NumericTraits< double >::Zero;
				}

				/** Initialize sumc. */
				double sumc = 0.0;

				/** Calculate the weighted mean over the neighborhood.
				 * mean = SUthis->m_i{ ci * x_i } / SUthis->m_i{ ci }
				 */
				for ( i = 0; i < neighborhoodSize; ++i )
				{
					/** Get current pixel in this neighborhood. */
					InputPixelType pix = nit.GetPixel( i );

					/** Get ci-value on current index. */
					ci = nit2.GetPixel( i );

					/** Calculate SUthis->m_i{ ci } and SUthis->m_i{ ci * x_i }. */
					sumc += ci;
					for ( j = 0; j < InputImageDimension; j++ )
					{
						sum[ j ] += ci * static_cast< double >( pix[ j ] );
					}
				}

				/** Get the mean value by dividing by sumc. */
				InputPixelType mean;
				for ( j = 0; j < InputImageDimension; j++ )
				{
					//if ( sumc == 0.0 ) mean[ j ] = 0.0;
					if ( sumc < 0.001 ) mean[ j ] = 0.0;
					else mean[ j ] = static_cast< ValueType >( sum[ j ] / sumc );
				}

				/** Get c. */
				c = nit2.GetCenterPixel();

				/** Set 'y = (1 - c) * x + c * mean' to the temporary output. */
				InputPixelType value = nit.GetCenterPixel() * ( 1.0 -	c ) + mean * c;

				/** Temporary if, so that value don't get to high! *
				for ( j = 0; j < InputImageDimension; j++ )
				{
					if ( value[ j ] > 1000.0 )
					{
						value[ j ] = 1000.0;
					}
				}

				/** Set it. */
				oit.Set( value );

				/** Increase all iterators. */
				++nit;
				++nit2;
				++oit;
				//progress.CompletedPixel();

			} // end while

			/** Copy outputtmp to output. */
			if ( this->GetNumberOfIterations() > 0 )
			{
				out_it.GoToBegin();
				oit.GoToBegin();
				while ( !out_it.IsAtEnd() )
				{
					out_it.Set( oit.Get() );
					++out_it;
					++oit;
				}
			} // end if

		} // end for NumberOfIterations

	} // end ThreadedGenerateData

	/**
	 * ********************* PrintSelf ******************************
	 *
	 * Standard "PrintSelf" method
	 */

	template < class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::PrintSelf( std::ostream& os, Indent indent) const
	{
		Superclass::PrintSelf( os, indent );
		os << indent << "Radius: " << this->m_Radius << std::endl;

	} // end PrintSelf

	/**
	 * ******************** SetGrayValueImage ***********************
	 */

	template< class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::SetGrayValueImage( GrayValueImageType * _arg )
	{
		if ( this->m_GrayValueImage != _arg )
		{
			this->m_GrayValueImage = _arg;
		}

	} // end SetGrayValueImage

	/**
	 * ******************** FilterGrayValueImage ********************
	 *
	 * This function reads an image u(x). This image is rescaled to
	 * intensities between 0.0 and 1.0, giving u~(x). Then we threshold
	 * the coefficient image or not.
	 */

	template< class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::FilterGrayValueImage(void)
	{
		/** This functions rescales the intensities of the input
		 * this->m_GrayValueImage between 0 and 1, and converts it to
		 * a double image. No thresholding is performed.
		 */

		/** Create this->m_Cx. */
		this->m_Cx = DoubleImageType::New();

		/** Rescale intensity of this->m_GrayValueImage to values between
		* 0.0 and 1.0.
		*/
		this->m_RescaleFilter = RescaleImageFilterType::New();
		this->m_RescaleFilter->SetOutputMinimum( 0.0 );
		this->m_RescaleFilter->SetOutputMaximum( 1.0 );
		this->m_RescaleFilter->SetInput( this->m_GrayValueImage );

		/** First set this->m_Cx = rescaleFilter->GetOutput(). */
		this->m_Cx = this->m_RescaleFilter->GetOutput();
		try
		{
			this->m_Cx->Update();
		}
		catch( itk::ExceptionObject & excp )
		{
			/** Add information to the exception. */
			excp.SetLocation( "VectorMeanDiffusionImageFilter - FilterGrayValueImage()" );
			std::string err_str = excp.GetDescription();
			err_str += "\nError occured while rescaling the intensities of the grayValue image.\n";
			excp.SetDescription( err_str );
			/** Pass the exception to an higher level. */
			throw excp;
		}

		/** Then, to avoid numerical problems, set everything
		 * smaller than 0.00001 to 0.00001 and everything larger
		 * than 0.99999 to 0.99999.
		 */
		ImageRegionIterator< DoubleImageType > it( this->m_Cx, this->m_Cx->GetLargestPossibleRegion() );
		it.GoToBegin();
		while ( !it.IsAtEnd() )
		{
			if ( it.Get() < 0.00001 ) it.Set( 0.00001 );
			if ( it.Get() > 0.99999 ) it.Set( 0.99999 );
			++it;
		}

		// \todo Is it possible to just use the rescale image filter with
		// minimum and maximum values of 0.00001 and 0.99999.

	} // end FilterGrayValueImage

} // end namespace itk

#endif // end #ifndef _itkVectorMeanDiffusionImageFilter_HXX__

<commit_msg>------------------------------------------------------------ MS:<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef _itkVectorMeanDiffusionImageFilter_HXX__
#define _itkVectorMeanDiffusionImageFilter_HXX__

#include "itkVectorMeanDiffusionImageFilter.h"

#include "itkNeighborhoodIterator.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "itkZeroFluxNeumannBoundaryCondition.h"
#include "itkProgressReporter.h"

//#include "itkCastImageFilter.h"
//#include "itkImageFileWriter.h"

namespace itk
{

	/**
	 * *********************** Constructor **************************
	 */

	template < class TInputImage, class TGrayValueImage >
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::VectorMeanDiffusionImageFilter()
	{
		/** Initialise things for the filter. */
		this->m_NumberOfIterations = 0;
		this->m_Radius.Fill(1);
		this->m_RescaleFilter = 0;
		this->m_GrayValueImage = 0;
		this->m_Cx = 0;

	} // end Constructor

	/**
	 * *************** GenerateInputRequestedRegion *****************
	 */

	template < class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::GenerateInputRequestedRegion() throw (InvalidRequestedRegionError)
	{
		// call the superclass' implementation of this method
		Superclass::GenerateInputRequestedRegion();

		// get pointers to the input and output
		typename Superclass::InputImagePointer inputPtr =
			const_cast< TInputImage * >( this->GetInput() );
		typename Superclass::OutputImagePointer outputPtr = this->GetOutput();

		if ( !inputPtr || !outputPtr )
    {
			return;
    }

		// get a copy of the input requested region (should equal the output
		// requested region)
		typename TInputImage::RegionType inputRequestedRegion;
		inputRequestedRegion = inputPtr->GetRequestedRegion();

		// pad the input requested region by the operator radius
		inputRequestedRegion.PadByRadius( this->m_Radius );

		// crop the input requested region at the input's largest possible region
		if ( inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) )
    {
			inputPtr->SetRequestedRegion( inputRequestedRegion );
			return;
    }
		else
    {
			// Couldn't crop the region (requested region is outside the largest
			// possible region).  Throw an exception.

			// store what we tried to request (prior to trying to crop)
			inputPtr->SetRequestedRegion( inputRequestedRegion );

			// build an exception
			InvalidRequestedRegionError e(__FILE__, __LINE__);
			OStringStream msg;
			msg << static_cast<const char *>(this->GetNameOfClass())
        << "::GenerateInputRequestedRegion()";
			e.SetLocation(msg.str().c_str());
			e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
			e.SetDataObject(inputPtr);
			throw e;
    }

	} // end GenerateInputRequestedRegion

	/**
	 * ********************** GenerateData **************************
	 */

	template < class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::GenerateData(void)
	{
		// \todo to avoid all the copying we can create a vector of
		// outputs of size this->GetNumberOfIterations(). The last
		// output should point to this->GetOutput(). In order to avoid
		// a big memory footprint, at some iteration k, memory of the
		// former iteration should be released: output[ k - 1 ] = 0,
		// and memory of the current iteration should only now be created:
		// output[ k ] = InputImageType::New(); ...; output[ k ]->Allocate().
		// Only for the last iteration: output[ k ]( this->GetOutput() ).

		/** Create feature image. */
		this->FilterGrayValueImage();

		/** Declare things. */
		unsigned int i, j;
		ZeroFluxNeumannBoundaryCondition< InputImageType >			nbc;
		ZeroFluxNeumannBoundaryCondition< DoubleImageType >			nbc2;
		NeighborhoodIterator< InputImageType >									nit;
		NeighborhoodIterator< DoubleImageType >									nit2;
		VectorRealType sum;

		/** Allocate output. */
		typename InputImageType::ConstPointer	input(	this->GetInput() );
		typename InputImageType::Pointer			output( this->GetOutput() );
		typename InputImageType::Pointer			outputtmp = InputImageType::New();

		output->SetRegions( input->GetLargestPossibleRegion() );
		output->Allocate();

		/** Allocate a temporary output image. */
		outputtmp->SetSpacing( input->GetSpacing() );
		outputtmp->SetOrigin( input->GetOrigin() );
		outputtmp->SetRegions( input->GetLargestPossibleRegion() );
		outputtmp->Allocate();

		// support progress methods/callbacks
		//ProgressReporter progress( this, threadId, outputRegionForThread.GetNumberOfPixels() );

		/** Copy input to output. */
		ImageRegionConstIterator< InputImageType >	in_it(
			input, input->GetLargestPossibleRegion() );
		ImageRegionIterator< InputImageType >				out_it(
			output, input->GetLargestPossibleRegion() );
		in_it.GoToBegin();
		out_it.GoToBegin();
		while ( !in_it.IsAtEnd() )
		{
			out_it.Set( in_it.Get() );
			++in_it;
			++out_it;
		}

		/** Setup neighborhood iterator for the output deformation image. */
		nit = NeighborhoodIterator< InputImageType >(
			this->m_Radius, output, output->GetLargestPossibleRegion() );
		unsigned int neighborhoodSize = nit.Size();
		nit.OverrideBoundaryCondition( &nbc );

		/** Setup neighborhood iterator for the "stiffness coefficient" image. */
		nit2 = NeighborhoodIterator< DoubleImageType >(
			this->m_Radius, this->m_Cx, this->m_Cx->GetLargestPossibleRegion() );
		nit2.OverrideBoundaryCondition( &nbc2 );

		/** Setup iterator over outputtmp. */
		ImageRegionIterator< InputImageType >				oit(
			outputtmp, input->GetLargestPossibleRegion() );

		/** Initialize c and ci. */
		double c = 0.0;
		double ci = 0.0;

		/** Loop over the number of iterations. */
		for ( unsigned int k = 0; k < this->GetNumberOfIterations(); k++ )
		{
			nit.GoToBegin();
			nit2.GoToBegin();
			oit.GoToBegin();

			/** The actual work. */
			while ( !nit.IsAtEnd() )
			{
				/** Speed up: do not filter locations where c(x) = 0. */
				if ( nit2.GetCenterPixel() < 0.000001 )
				{
					/** Just copy input to output. */
					oit.Set( nit.GetCenterPixel() );
					/** Increase all iterators. */
					++nit;
					++nit2;
					++oit;
					//progress.CompletedPixel();
				}
				else
				{
					/** Initialize the sum to 0. */
					for ( j = 0; j < InputImageDimension; j++ )
					{
						sum[ j ] = NumericTraits< double >::Zero;
					}

					/** Initialize sumc. */
					double sumc = 0.0;

					/** Calculate the weighted mean over the neighborhood.
					 * mean = SUthis->m_i{ ci * x_i } / SUthis->m_i{ ci }
					 */
					for ( i = 0; i < neighborhoodSize; ++i )
					{
						/** Get current pixel in this neighborhood. */
						InputPixelType pix = nit.GetPixel( i );

						/** Get ci-value on current index. */
						ci = nit2.GetPixel( i );

						/** Calculate SUthis->m_i{ ci } and SUthis->m_i{ ci * x_i }. */
						sumc += ci;
						for ( j = 0; j < InputImageDimension; j++ )
						{
							sum[ j ] += ci * static_cast< double >( pix[ j ] );
						}
					}

					/** Get the mean value by dividing by sumc. */
					InputPixelType mean;
					for ( j = 0; j < InputImageDimension; j++ )
					{
						//if ( sumc == 0.0 ) mean[ j ] = 0.0;
						if ( sumc < 0.00001 ) mean[ j ] = 0.0;
						else mean[ j ] = static_cast< ValueType >( sum[ j ] / sumc );
					}

					/** Get c. */
					c = nit2.GetCenterPixel();

					/** Set 'y = (1 - c) * x + c * mean' to the temporary output. */
					InputPixelType value = nit.GetCenterPixel() * ( 1.0 -	c ) + mean * c;

					/** Temporary if, so that value don't get to high! *
					for ( j = 0; j < InputImageDimension; j++ )
					{
					if ( value[ j ] > 1000.0 )
					{
					value[ j ] = 1000.0;
					}
					}

					/** Set it. */
					oit.Set( value );

					/** Increase all iterators. */
					++nit;
					++nit2;
					++oit;
					//progress.CompletedPixel();

				} // end while

				/** Copy outputtmp to output. */
				if ( this->GetNumberOfIterations() > 0 )
				{
					out_it.GoToBegin();
					oit.GoToBegin();
					while ( !out_it.IsAtEnd() )
					{
						out_it.Set( oit.Get() );
						++out_it;
						++oit;
					}
				} // end if GetNumberOfIterations

			} // end if c < 0.000001

		} // end for NumberOfIterations

	} // end ThreadedGenerateData

	/**
	 * ********************* PrintSelf ******************************
	 *
	 * Standard "PrintSelf" method
	 */

	template < class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::PrintSelf( std::ostream& os, Indent indent) const
	{
		Superclass::PrintSelf( os, indent );
		os << indent << "Radius: " << this->m_Radius << std::endl;

	} // end PrintSelf

	/**
	 * ******************** SetGrayValueImage ***********************
	 */

	template< class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::SetGrayValueImage( GrayValueImageType * _arg )
	{
		if ( this->m_GrayValueImage != _arg )
		{
			this->m_GrayValueImage = _arg;
		}

	} // end SetGrayValueImage

	/**
	 * ******************** FilterGrayValueImage ********************
	 *
	 * This function reads an image u(x). This image is rescaled to
	 * intensities between 0.0 and 1.0, giving u~(x). Then we threshold
	 * the coefficient image or not.
	 */

	template< class TInputImage, class TGrayValueImage >
		void
		VectorMeanDiffusionImageFilter< TInputImage, TGrayValueImage >
		::FilterGrayValueImage(void)
	{
		/** This functions rescales the intensities of the input
		 * this->m_GrayValueImage between 0 and 1, and converts it to
		 * a double image. No thresholding is performed.
		 */

		/** Create this->m_Cx. */
		this->m_Cx = DoubleImageType::New();

		/** Rescale intensity of this->m_GrayValueImage to values between
		* 0.0 and 1.0.
		*/
		this->m_RescaleFilter = RescaleImageFilterType::New();
		this->m_RescaleFilter->SetOutputMinimum( 0.000001 );
		this->m_RescaleFilter->SetOutputMaximum( 0.999999 );
		this->m_RescaleFilter->SetInput( this->m_GrayValueImage );

		/** First set this->m_Cx = rescaleFilter->GetOutput(). */
		this->m_Cx = this->m_RescaleFilter->GetOutput();
		try
		{
			this->m_Cx->Update();
		}
		catch( itk::ExceptionObject & excp )
		{
			/** Add information to the exception. */
			excp.SetLocation( "VectorMeanDiffusionImageFilter - FilterGrayValueImage()" );
			std::string err_str = excp.GetDescription();
			err_str += "\nError occured while rescaling the intensities of the grayValue image.\n";
			excp.SetDescription( err_str );
			/** Pass the exception to an higher level. */
			throw excp;
		}

	} // end FilterGrayValueImage

} // end namespace itk

#endif // end #ifndef _itkVectorMeanDiffusionImageFilter_HXX__

<|endoftext|>


<commit_before>/**
 * @file   llcapabilitylistener_test.cpp
 * @author Nat Goodspeed
 * @date   2008-12-31
 * @brief  Test for llcapabilitylistener.cpp.
 *
 * $LicenseInfo:firstyear=2008&license=viewergpl$
 *
 * Copyright (c) 2008-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

// Precompiled header
#include "../llviewerprecompiledheaders.h"
// Own header
#include "../llcapabilitylistener.h"
// STL headers
#include <stdexcept>
#include <map>
#include <vector>
// std headers
// external library headers
#include "boost/bind.hpp"
// other Linden headers
#include "../test/lltut.h"
#include "../llcapabilityprovider.h"
#include "lluuid.h"
#include "tests/networkio.h"
#include "tests/commtest.h"
#include "tests/wrapllerrs.h"
#include "stringize.h"

#if defined(LL_WINDOWS)
#pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
#endif

/*****************************************************************************
*   TestCapabilityProvider
*****************************************************************************/
struct TestCapabilityProvider: public LLCapabilityProvider
{
    TestCapabilityProvider(const LLHost& host):
        mHost(host)
    {}

    std::string getCapability(const std::string& cap) const
    {
        CapMap::const_iterator found = mCaps.find(cap);
        if (found != mCaps.end())
            return found->second;
        // normal LLViewerRegion lookup failure mode
        return "";
    }
    void setCapability(const std::string& cap, const std::string& url)
    {
        mCaps[cap] = url;
    }
    LLHost getHost() const { return mHost; }
    std::string getDescription() const { return "TestCapabilityProvider"; }

    LLHost mHost;
    typedef std::map<std::string, std::string> CapMap;
    CapMap mCaps;
};

/*****************************************************************************
*   Dummy LLMessageSystem methods
*****************************************************************************/
/*==========================================================================*|
// This doesn't work because we're already linking in llmessage.a, and we get
// duplicate-symbol errors from the linker. Perhaps if I wanted to go through
// the exercise of providing dummy versions of every single symbol defined in
// message.o -- maybe some day.
typedef std::vector< std::pair<std::string, std::string> > StringPairVector;
StringPairVector call_history;

S32 LLMessageSystem::sendReliable(const LLHost& host)
{
    call_history.push_back(StringPairVector::value_type("sendReliable", stringize(host)));
    return 0;
}
|*==========================================================================*/

/*****************************************************************************
*   TUT
*****************************************************************************/
namespace tut
{
    struct llcapears_data: public commtest_data
    {
        TestCapabilityProvider provider;
        LLCapabilityListener regionListener;
        LLEventPump& regionPump;

        llcapears_data():
            provider(host),
            regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()),
            regionPump(regionListener.getCapAPI())
        {
            provider.setCapability("good", server + "capability-test");
            provider.setCapability("fail", server + "fail");
        }
    };
    typedef test_group<llcapears_data> llcapears_group;
    typedef llcapears_group::object llcapears_object;
    llcapears_group llsdmgr("llcapabilitylistener");

    template<> template<>
    void llcapears_object::test<1>()
    {
        LLSD request, body;
        body["data"] = "yes";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        std::string threw;
        try
        {
            WrapLL_ERRS capture;
            regionPump.post(request);
        }
        catch (const WrapLL_ERRS::FatalException& e)
        {
            threw = e.what();
        }
        ensure_contains("missing capability name", threw, "without 'message' key");
    }

    template<> template<>
    void llcapears_object::test<2>()
    {
        LLSD request, body;
        body["data"] = "yes";
        request["message"] = "good";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        regionPump.post(request);
        ensure("got response", netio.pump());
        ensure("success response", success);
        ensure_equals(result.asString(), "success");

        body["status"] = 499;
        body["reason"] = "custom error message";
        request["message"] = "fail";
        request["payload"] = body;
        regionPump.post(request);
        ensure("got response", netio.pump());
        ensure("failure response", ! success);
        ensure_equals(result["status"].asInteger(), body["status"].asInteger());
        ensure_equals(result["reason"].asString(),  body["reason"].asString());
    }

    template<> template<>
    void llcapears_object::test<3>()
    {
        LLSD request, body;
        body["data"] = "yes";
        request["message"] = "unknown";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        std::string threw;
        try
        {
            WrapLL_ERRS capture;
            regionPump.post(request);
        }
        catch (const WrapLL_ERRS::FatalException& e)
        {
            threw = e.what();
        }
        ensure_contains("bad capability name", threw, "unsupported capability");
    }

    struct TestMapper: public LLCapabilityListener::CapabilityMapper
    {
        // Instantiator gets to specify whether mapper expects a reply.
        // I'd really like to be able to test CapabilityMapper::buildMessage()
        // functionality, too, but -- even though LLCapabilityListener accepts
        // the LLMessageSystem* that it passes to CapabilityMapper --
        // LLMessageSystem::sendReliable(const LLHost&) isn't virtual, so it's
        // not helpful to pass a subclass instance. I suspect that making any
        // LLMessageSystem methods virtual would provoke howls of outrage,
        // given how heavily it's used. Nor can I just provide a local
        // definition of LLMessageSystem::sendReliable(const LLHost&) because
        // we're already linking in the rest of message.o via llmessage.a, and
        // that produces duplicate-symbol link errors.
        TestMapper(const std::string& replyMessage = std::string()):
            LLCapabilityListener::CapabilityMapper("test", replyMessage)
        {}
        virtual void buildMessage(LLMessageSystem* msg,
                                  const LLUUID& agentID,
                                  const LLUUID& sessionID,
                                  const std::string& capabilityName,
                                  const LLSD& payload) const
        {
            msg->newMessageFast(_PREHASH_SetStartLocationRequest);
            msg->nextBlockFast( _PREHASH_AgentData);
            msg->addUUIDFast(_PREHASH_AgentID, agentID);
            msg->addUUIDFast(_PREHASH_SessionID, sessionID);
            msg->nextBlockFast( _PREHASH_StartLocationData);
            // corrected by sim
            msg->addStringFast(_PREHASH_SimName, "");
            msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
/*==========================================================================*|
            msg->addVector3Fast(_PREHASH_LocationPos,
                                ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
            msg->addVector3Fast(_PREHASH_LocationLookAt,
                                ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
|*==========================================================================*/
        }
    };

    template<> template<>
    void llcapears_object::test<4>()
    {
        TestMapper testMapper("WantReply");
        LLSD request, body;
        body["data"] = "yes";
        request["message"] = "test";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        std::string threw;
        try
        {
            WrapLL_ERRS capture;
            regionPump.post(request);
        }
        catch (const WrapLL_ERRS::FatalException& e)
        {
            threw = e.what();
        }
        ensure_contains("capability mapper wants reply", threw, "unimplemented support for reply message");
    }

    template<> template<>
    void llcapears_object::test<5>()
    {
        TestMapper testMapper;
        std::string threw;
        try
        {
            TestMapper testMapper2;
        }
        catch (const std::runtime_error& e)
        {
            threw = e.what();
        }
        ensure_contains("no dup cap mapper", threw, "DupCapMapper");
    }
}
<commit_msg>Yet again more fixups for compile errors after the last merge...<commit_after>/**
 * @file   llcapabilitylistener_test.cpp
 * @author Nat Goodspeed
 * @date   2008-12-31
 * @brief  Test for llcapabilitylistener.cpp.
 *
 * $LicenseInfo:firstyear=2008&license=viewergpl$
 *
 * Copyright (c) 2008-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

// Precompiled header
#include "../llviewerprecompiledheaders.h"
// Own header
#include "../llcapabilitylistener.h"
// STL headers
#include <stdexcept>
#include <map>
#include <vector>
// std headers
// external library headers
#include "boost/bind.hpp"
// other Linden headers
#include "../test/lltut.h"
#include "../llcapabilityprovider.h"
#include "lluuid.h"
#include "tests/networkio.h"
#include "tests/commtest.h"
#include "tests/wrapllerrs.h"
#include "message.h"
#include "stringize.h"

#if defined(LL_WINDOWS)
#pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
#endif

/*****************************************************************************
*   TestCapabilityProvider
*****************************************************************************/
struct TestCapabilityProvider: public LLCapabilityProvider
{
    TestCapabilityProvider(const LLHost& host):
        mHost(host)
    {}

    std::string getCapability(const std::string& cap) const
    {
        CapMap::const_iterator found = mCaps.find(cap);
        if (found != mCaps.end())
            return found->second;
        // normal LLViewerRegion lookup failure mode
        return "";
    }
    void setCapability(const std::string& cap, const std::string& url)
    {
        mCaps[cap] = url;
    }
    LLHost getHost() const { return mHost; }
    std::string getDescription() const { return "TestCapabilityProvider"; }

    LLHost mHost;
    typedef std::map<std::string, std::string> CapMap;
    CapMap mCaps;
};

/*****************************************************************************
*   Dummy LLMessageSystem methods
*****************************************************************************/
/*==========================================================================*|
// This doesn't work because we're already linking in llmessage.a, and we get
// duplicate-symbol errors from the linker. Perhaps if I wanted to go through
// the exercise of providing dummy versions of every single symbol defined in
// message.o -- maybe some day.
typedef std::vector< std::pair<std::string, std::string> > StringPairVector;
StringPairVector call_history;

S32 LLMessageSystem::sendReliable(const LLHost& host)
{
    call_history.push_back(StringPairVector::value_type("sendReliable", stringize(host)));
    return 0;
}
|*==========================================================================*/

/*****************************************************************************
*   TUT
*****************************************************************************/
namespace tut
{
    struct llcapears_data: public commtest_data
    {
        TestCapabilityProvider provider;
        LLCapabilityListener regionListener;
        LLEventPump& regionPump;

        llcapears_data():
            provider(host),
            regionListener("testCapabilityListener", NULL, provider, LLUUID(), LLUUID()),
            regionPump(regionListener.getCapAPI())
        {
            provider.setCapability("good", server + "capability-test");
            provider.setCapability("fail", server + "fail");
        }
    };
    typedef test_group<llcapears_data> llcapears_group;
    typedef llcapears_group::object llcapears_object;
    llcapears_group llsdmgr("llcapabilitylistener");

    template<> template<>
    void llcapears_object::test<1>()
    {
        LLSD request, body;
        body["data"] = "yes";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        std::string threw;
        try
        {
            WrapLL_ERRS capture;
            regionPump.post(request);
        }
        catch (const WrapLL_ERRS::FatalException& e)
        {
            threw = e.what();
        }
        ensure_contains("missing capability name", threw, "without 'message' key");
    }

    template<> template<>
    void llcapears_object::test<2>()
    {
        LLSD request, body;
        body["data"] = "yes";
        request["message"] = "good";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        regionPump.post(request);
        ensure("got response", netio.pump());
        ensure("success response", success);
        ensure_equals(result.asString(), "success");

        body["status"] = 499;
        body["reason"] = "custom error message";
        request["message"] = "fail";
        request["payload"] = body;
        regionPump.post(request);
        ensure("got response", netio.pump());
        ensure("failure response", ! success);
        ensure_equals(result["status"].asInteger(), body["status"].asInteger());
        ensure_equals(result["reason"].asString(),  body["reason"].asString());
    }

    template<> template<>
    void llcapears_object::test<3>()
    {
        LLSD request, body;
        body["data"] = "yes";
        request["message"] = "unknown";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        std::string threw;
        try
        {
            WrapLL_ERRS capture;
            regionPump.post(request);
        }
        catch (const WrapLL_ERRS::FatalException& e)
        {
            threw = e.what();
        }
        ensure_contains("bad capability name", threw, "unsupported capability");
    }

    struct TestMapper: public LLCapabilityListener::CapabilityMapper
    {
        // Instantiator gets to specify whether mapper expects a reply.
        // I'd really like to be able to test CapabilityMapper::buildMessage()
        // functionality, too, but -- even though LLCapabilityListener accepts
        // the LLMessageSystem* that it passes to CapabilityMapper --
        // LLMessageSystem::sendReliable(const LLHost&) isn't virtual, so it's
        // not helpful to pass a subclass instance. I suspect that making any
        // LLMessageSystem methods virtual would provoke howls of outrage,
        // given how heavily it's used. Nor can I just provide a local
        // definition of LLMessageSystem::sendReliable(const LLHost&) because
        // we're already linking in the rest of message.o via llmessage.a, and
        // that produces duplicate-symbol link errors.
        TestMapper(const std::string& replyMessage = std::string()):
            LLCapabilityListener::CapabilityMapper("test", replyMessage)
        {}
        virtual void buildMessage(LLMessageSystem* msg,
                                  const LLUUID& agentID,
                                  const LLUUID& sessionID,
                                  const std::string& capabilityName,
                                  const LLSD& payload) const
        {
            msg->newMessageFast(_PREHASH_SetStartLocationRequest);
            msg->nextBlockFast( _PREHASH_AgentData);
            msg->addUUIDFast(_PREHASH_AgentID, agentID);
            msg->addUUIDFast(_PREHASH_SessionID, sessionID);
            msg->nextBlockFast( _PREHASH_StartLocationData);
            // corrected by sim
            msg->addStringFast(_PREHASH_SimName, "");
            msg->addU32Fast(_PREHASH_LocationID, payload["HomeLocation"]["LocationId"].asInteger());
/*==========================================================================*|
            msg->addVector3Fast(_PREHASH_LocationPos,
                                ll_vector3_from_sdmap(payload["HomeLocation"]["LocationPos"]));
            msg->addVector3Fast(_PREHASH_LocationLookAt,
                                ll_vector3_from_sdmap(payload["HomeLocation"]["LocationLookAt"]));
|*==========================================================================*/
        }
    };

    template<> template<>
    void llcapears_object::test<4>()
    {
        TestMapper testMapper("WantReply");
        LLSD request, body;
        body["data"] = "yes";
        request["message"] = "test";
        request["payload"] = body;
        request["reply"] = replyPump.getName();
        request["error"] = errorPump.getName();
        std::string threw;
        try
        {
            WrapLL_ERRS capture;
            regionPump.post(request);
        }
        catch (const WrapLL_ERRS::FatalException& e)
        {
            threw = e.what();
        }
        ensure_contains("capability mapper wants reply", threw, "unimplemented support for reply message");
    }

    template<> template<>
    void llcapears_object::test<5>()
    {
        TestMapper testMapper;
        std::string threw;
        try
        {
            TestMapper testMapper2;
        }
        catch (const std::runtime_error& e)
        {
            threw = e.what();
        }
        ensure_contains("no dup cap mapper", threw, "DupCapMapper");
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <boost/test/unit_test.hpp>
#include "flat_mutation_reader.hh"

// Intended to be called in a seastar thread
class flat_reader_assertions {
    flat_mutation_reader _reader;
private:
    mutation_fragment_opt read_next() {
        return _reader().get0();
    }
public:
    flat_reader_assertions(flat_mutation_reader reader)
        : _reader(std::move(reader))
    { }

    flat_reader_assertions& produces_partition_start(const dht::decorated_key& dk) {
        BOOST_TEST_MESSAGE(sprint("Expecting partition start with key %s", dk));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got end of stream", dk));
        }
        if (!mfopt->is_partition_start()) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        if (!mfopt->as_partition_start().key().equal(*_reader.schema(), dk)) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_static_row() {
        BOOST_TEST_MESSAGE(sprint("Expecting static row"));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL("Expected static row, got end of stream");
        }
        if (!mfopt->is_static_row()) {
            BOOST_FAIL(sprint("Expected static row, got: %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_row_with_key(const clustering_key& ck) {
        BOOST_TEST_MESSAGE(sprint("Expect %s", ck));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected row with key %s, but got end of stream", ck));
        }
        if (!mfopt->is_clustering_row()) {
            BOOST_FAIL(sprint("Expected row with key %s, but got %s", ck, *mfopt));
        }
        auto& actual = mfopt->as_clustering_row().key();
        if (!actual.equal(*_reader.schema(), ck)) {
            BOOST_FAIL(sprint("Expected row with key %s, but key is %s", ck, actual));
        }
        return *this;
    }

    flat_reader_assertions& produces_partition_end() {
        BOOST_TEST_MESSAGE("Expecting partition end");
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected partition end but got end of stream"));
        }
        if (!mfopt->is_end_of_partition()) {
            BOOST_FAIL(sprint("Expected partition end but got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_end_of_stream() {
        BOOST_TEST_MESSAGE("Expecting end of stream");
        auto mfopt = read_next();
        if (bool(mfopt)) {
            BOOST_FAIL(sprint("Expected end of stream, got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& fast_forward_to(const dht::partition_range& pr) {
        _reader.fast_forward_to(pr);
        return *this;
    }

    flat_reader_assertions& next_partition() {
        _reader.next_partition();
        return *this;
    }

    flat_reader_assertions& fast_forward_to(position_range pr) {
        _reader.fast_forward_to(std::move(pr));
        return *this;
    }
};

inline
flat_reader_assertions assert_that(flat_mutation_reader r) {
    return { std::move(r) };
}
<commit_msg>tests/flat_mutation_reader_assertion: add produces_partition()<commit_after>/*
 * Copyright (C) 2017 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include <boost/test/unit_test.hpp>
#include "flat_mutation_reader.hh"

// Intended to be called in a seastar thread
class flat_reader_assertions {
    flat_mutation_reader _reader;
private:
    mutation_fragment_opt read_next() {
        return _reader().get0();
    }
public:
    flat_reader_assertions(flat_mutation_reader reader)
        : _reader(std::move(reader))
    { }

    flat_reader_assertions& produces_partition_start(const dht::decorated_key& dk,
                                                     stdx::optional<tombstone> tomb = stdx::nullopt) {
        BOOST_TEST_MESSAGE(sprint("Expecting partition start with key %s", dk));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got end of stream", dk));
        }
        if (!mfopt->is_partition_start()) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        if (!mfopt->as_partition_start().key().equal(*_reader.schema(), dk)) {
            BOOST_FAIL(sprint("Expected: partition start with key %s, got: %s", dk, *mfopt));
        }
        if (tomb && mfopt->as_partition_start().partition_tombstone() != *tomb) {
            BOOST_FAIL(sprint("Expected: partition start with tombstone %s, got: %s", *tomb, *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_static_row() {
        BOOST_TEST_MESSAGE(sprint("Expecting static row"));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL("Expected static row, got end of stream");
        }
        if (!mfopt->is_static_row()) {
            BOOST_FAIL(sprint("Expected static row, got: %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_row_with_key(const clustering_key& ck) {
        BOOST_TEST_MESSAGE(sprint("Expect %s", ck));
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected row with key %s, but got end of stream", ck));
        }
        if (!mfopt->is_clustering_row()) {
            BOOST_FAIL(sprint("Expected row with key %s, but got %s", ck, *mfopt));
        }
        auto& actual = mfopt->as_clustering_row().key();
        if (!actual.equal(*_reader.schema(), ck)) {
            BOOST_FAIL(sprint("Expected row with key %s, but key is %s", ck, actual));
        }
        return *this;
    }

    flat_reader_assertions& produces_partition_end() {
        BOOST_TEST_MESSAGE("Expecting partition end");
        auto mfopt = read_next();
        if (!mfopt) {
            BOOST_FAIL(sprint("Expected partition end but got end of stream"));
        }
        if (!mfopt->is_end_of_partition()) {
            BOOST_FAIL(sprint("Expected partition end but got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_end_of_stream() {
        BOOST_TEST_MESSAGE("Expecting end of stream");
        auto mfopt = read_next();
        if (bool(mfopt)) {
            BOOST_FAIL(sprint("Expected end of stream, got %s", *mfopt));
        }
        return *this;
    }

    flat_reader_assertions& produces_partition(const mutation& m) {
        BOOST_TEST_MESSAGE(sprint("Expecting a partition with key %s", m));
        produces_partition_start(m.decorated_key(), m.partition().partition_tombstone());
        auto produced_m = mutation(m.decorated_key(), m.schema());
        produced_m.partition().apply(m.partition().partition_tombstone());
        auto mfopt = read_next();
        while (mfopt && !mfopt->is_end_of_partition()) {
            produced_m.apply(*mfopt);
            mfopt = read_next();
        }
        if (!mfopt) {
            BOOST_FAIL("Expected a partition end before the end of stream");
        }
        if (m != produced_m) {
            BOOST_FAIL(sprint("Expected: partition %s, got: %s", m, produced_m));
        }
        return *this;
    }

    flat_reader_assertions& fast_forward_to(const dht::partition_range& pr) {
        _reader.fast_forward_to(pr);
        return *this;
    }

    flat_reader_assertions& next_partition() {
        _reader.next_partition();
        return *this;
    }

    flat_reader_assertions& fast_forward_to(position_range pr) {
        _reader.fast_forward_to(std::move(pr));
        return *this;
    }
};

inline
flat_reader_assertions assert_that(flat_mutation_reader r) {
    return { std::move(r) };
}
<|endoftext|>


<commit_before>#include <aleph/persistentHomology/ConnectedComponents.hh>

#include <aleph/topology/filtrations/Data.hh>

#include <aleph/topology/io/SimplicialComplexReader.hh>

#include <aleph/topology/Simplex.hh>
#include <aleph/topology/SimplicialComplex.hh>

#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <unordered_map>

using DataType          = double;
using VertexType        = unsigned;
using Simplex           = aleph::topology::Simplex<DataType, VertexType>;
using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;
using Filtration        = aleph::topology::filtrations::Data<Simplex>;
using Edge              = std::pair<VertexType, VertexType>;

namespace
{

struct SizeFunctor
{
  void initialize( VertexType v )
  {
    _componentSize[v] = 1;
  }

  void operator()( VertexType younger,
                   VertexType older,
                   DataType creation,
                   DataType destruction,
                   VertexType u,
                   VertexType v )
  {
    if( u > v )
      std::swap(u,v);

    _componentSize[older]                 += _componentSize[younger];
    _edgeRelevance[ std::make_pair(u,v) ]  = _componentSize[older];

    std::cerr << "* Edge " << "(" << u << "," << v << "): "
              << _edgeRelevance[ std::make_pair(u,v) ]
              << " "
              << "[" << creation << "," << destruction << "]"
              << "\n";
  }

  void operator()( VertexType /* root */,
                   DataType /* creation */ )
  {
  }

  std::unordered_map<VertexType, unsigned> _componentSize;
  std::map<Edge, unsigned>                 _edgeRelevance;
};

}

int main( int argc, char** argv )
{
  if( argc <= 1 )
    return -1;

  std::string filename = argv[1];

  SimplicialComplex K;

  aleph::topology::io::SimplicialComplexReader reader;
  reader( filename, K );

  K.sort( Filtration() );

  SizeFunctor sf;

  auto&& tuple = aleph::calculateZeroDimensionalPersistenceDiagram<Simplex, aleph::traits::PersistencePairingCalculation<aleph::PersistencePairing<VertexType> > >( K, sf );
  auto&& pd    = std::get<0>( tuple );
  auto&& pp    = std::get<1>( tuple );

  std::cout << pd << "\n";
}
<commit_msg>Improved relevance calculation<commit_after>#include <aleph/persistentHomology/ConnectedComponents.hh>

#include <aleph/topology/filtrations/Data.hh>

#include <aleph/topology/io/SimplicialComplexReader.hh>

#include <aleph/topology/Simplex.hh>
#include <aleph/topology/SimplicialComplex.hh>

#include <iostream>
#include <map>
#include <string>
#include <utility>
#include <unordered_map>

using DataType          = double;
using VertexType        = unsigned;
using Simplex           = aleph::topology::Simplex<DataType, VertexType>;
using SimplicialComplex = aleph::topology::SimplicialComplex<Simplex>;
using Filtration        = aleph::topology::filtrations::Data<Simplex>;
using Edge              = std::pair<VertexType, VertexType>;

namespace
{

struct SizeFunctor
{
  void initialize( VertexType v )
  {
    _componentSize[v] = 1;
  }

  void operator()( VertexType younger,
                   VertexType older,
                   DataType creation,
                   DataType destruction,
                   VertexType u,
                   VertexType v )
  {
    if( u > v )
      std::swap(u,v);

    auto&& e         = std::make_pair(u,v);
    double c_older   = _componentSize[older];
    double c_younger = _componentSize[younger];

    _componentSize[older] += _componentSize[younger];
    _edgeRelevance[ e ]    = std::min( c_older, c_younger)  / std::max( c_older, c_younger );
    _edgeStrength [ e ]    = _componentSize[older];

    std::cerr << "* Edge " << "(" << u << "," << v << "): "
              << _edgeRelevance[e]
              << " "
              << "[" << creation << "," << destruction << "]"
              << "\n";
  }

  void operator()( VertexType /* root */,
                   DataType /* creation */ )
  {
  }

  std::unordered_map<VertexType, unsigned> _componentSize;
  std::map<Edge, double>                   _edgeRelevance;
  std::map<Edge, unsigned>                 _edgeStrength;
};

}

int main( int argc, char** argv )
{
  if( argc <= 1 )
    return -1;

  std::string filename = argv[1];

  SimplicialComplex K;

  aleph::topology::io::SimplicialComplexReader reader;
  reader( filename, K );

  K.sort( Filtration() );

  SizeFunctor sf;

  auto&& tuple = aleph::calculateZeroDimensionalPersistenceDiagram<Simplex, aleph::traits::PersistencePairingCalculation<aleph::PersistencePairing<VertexType> > >( K, sf );
  auto&& pd    = std::get<0>( tuple );
  auto&& pp    = std::get<1>( tuple );

  std::cout << pd << "\n";
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <boost/algorithm/string/replace.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
#include <iostream>
#include <votca/tools/application.h>
#include <votca/tools/globals.h>
#include <votca/tools/property.h>
#include <votca/tools/propertyiomanipulator.h>
#include <votca/tools/version.h>

using namespace std;
using namespace votca::tools;
namespace po = boost::program_options;

class VotcaProperty : public Application {

 public:
  VotcaProperty();
  ~VotcaProperty() override;

  string ProgramName() override { return "votca_property"; }

  void HelpText(ostream& out) override {
    out << "Helper for parsing XML files";
  }

  void Initialize() override {

    format = "XML";
    level = 1;

    AddProgramOptions()("file", po::value<string>(), "xml file to parse")(
        "format", po::value<string>(), "output format [XML TXT TEX]")(
        "level", po::value<votca::Index>(), "output from this level ");
  };

  bool EvaluateOptions() override {
    CheckRequired("file", "Missing XML file");
    return true;
  };

  void Run() override {

    file = _op_vm["file"].as<string>();

    if (_op_vm.count("format")) {
      format = _op_vm["format"].as<string>();
    }
    if (_op_vm.count("level")) {
      level = _op_vm["level"].as<votca::Index>();
    }

    try {

      Property p;
      map<string, PropertyIOManipulator*> _mformat;
      _mformat["XML"] = &XML;
      _mformat["TXT"] = &TXT;
      _mformat["TEX"] = &TEX;
      _mformat["HLP"] = &HLP;
      p.LoadFromXML(file);

      if (_mformat.find(format) != _mformat.end()) {
        PropertyIOManipulator* piom = _mformat.find(format)->second;
        piom->setLevel(level);
        piom->setIndentation("");
        piom->setColorScheme<csRGB>();
        cout << *piom << p;
      } else {
        cout << "format " << format << " not supported \n";
      }

    } catch (std::exception& error) {
      cerr << "an error occurred:\n" << error.what() << endl;
    }
  };

 private:
  string file;
  string format;
  votca::Index level;
};

VotcaProperty::VotcaProperty(void) = default;

VotcaProperty::~VotcaProperty(void) = default;

int main(int argc, char** argv) {
  VotcaProperty vp;
  return vp.Exec(argc, argv);
}
<commit_msg>Changed system include to local include in tools<commit_after>/*
 * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "../../include/votca/tools/application.h"
#include "../../include/votca/tools/globals.h"
#include "../../include/votca/tools/property.h"
#include "../../include/votca/tools/propertyiomanipulator.h"
#include "../../include/votca/tools/version.h"
#include <boost/algorithm/string/replace.hpp>
#include <boost/format.hpp>
#include <boost/program_options.hpp>
#include <iostream>

using namespace std;
using namespace votca::tools;
namespace po = boost::program_options;

class VotcaProperty : public Application {

 public:
  VotcaProperty();
  ~VotcaProperty() override;

  string ProgramName() override { return "votca_property"; }

  void HelpText(ostream& out) override {
    out << "Helper for parsing XML files";
  }

  void Initialize() override {

    format = "XML";
    level = 1;

    AddProgramOptions()("file", po::value<string>(), "xml file to parse")(
        "format", po::value<string>(), "output format [XML TXT TEX]")(
        "level", po::value<votca::Index>(), "output from this level ");
  };

  bool EvaluateOptions() override {
    CheckRequired("file", "Missing XML file");
    return true;
  };

  void Run() override {

    file = _op_vm["file"].as<string>();

    if (_op_vm.count("format")) {
      format = _op_vm["format"].as<string>();
    }
    if (_op_vm.count("level")) {
      level = _op_vm["level"].as<votca::Index>();
    }

    try {

      Property p;
      map<string, PropertyIOManipulator*> _mformat;
      _mformat["XML"] = &XML;
      _mformat["TXT"] = &TXT;
      _mformat["TEX"] = &TEX;
      _mformat["HLP"] = &HLP;
      p.LoadFromXML(file);

      if (_mformat.find(format) != _mformat.end()) {
        PropertyIOManipulator* piom = _mformat.find(format)->second;
        piom->setLevel(level);
        piom->setIndentation("");
        piom->setColorScheme<csRGB>();
        cout << *piom << p;
      } else {
        cout << "format " << format << " not supported \n";
      }

    } catch (std::exception& error) {
      cerr << "an error occurred:\n" << error.what() << endl;
    }
  };

 private:
  string file;
  string format;
  votca::Index level;
};

VotcaProperty::VotcaProperty(void) = default;

VotcaProperty::~VotcaProperty(void) = default;

int main(int argc, char** argv) {
  VotcaProperty vp;
  return vp.Exec(argc, argv);
}
<|endoftext|>