<commit_before>#ifndef SILICIUM_REACTIVE_LINUX_INOTIFY_HPP
#define SILICIUM_REACTIVE_LINUX_INOTIFY_HPP

#include <silicium/observable/observer.hpp>
#include <silicium/error_or.hpp>
#include <silicium/exchange.hpp>
#include <silicium/linux/inotify_watch_descriptor.hpp>
#include <silicium/path.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/swap.hpp>
#include <boost/optional.hpp>
#include <boost/ref.hpp>
#include <dirent.h>

namespace Si
{
	namespace linux
	{
		struct file_notification
		{
			boost::uint32_t mask;
			path name;

			file_notification() BOOST_NOEXCEPT
			    : mask(0)
			{
			}

			explicit file_notification(boost::uint32_t mask, path name) BOOST_NOEXCEPT
			    : mask(mask)
			    , name(std::move(name))
			{
			}
		};

		struct inotify_observable
		{
			typedef std::vector<file_notification> element_type;

			inotify_observable() BOOST_NOEXCEPT
			{
			}

			explicit inotify_observable(boost::asio::io_service &io)
				: notifier(Si::make_unique<boost::asio::posix::stream_descriptor>(boost::ref(io)))
			{
				int fd = inotify_init();
				if (fd < 0)
				{
					throw boost::system::system_error(errno, boost::system::posix_category);
				}
				try
				{
					notifier->assign(fd);
				}
				catch (...)
				{
					close(fd);
					throw;
				}
			}

			error_or<watch_descriptor> watch(boost::filesystem::path const &target, boost::uint32_t mask) BOOST_NOEXCEPT
			{
				assert(notifier);
				int const wd = inotify_add_watch(notifier->native_handle(), target.c_str(), mask);
				if (wd < 0)
				{
					return boost::system::error_code(errno, boost::system::posix_category);
				}
				return watch_descriptor(notifier->native_handle(), wd);
			}

			template <class Observer>
			void async_get_one(Observer &&receiver)
			{
				std::size_t const min_buffer_size = sizeof(inotify_event) + NAME_MAX + 1;
				std::size_t const additional_buffer = 8192;
				read_buffer.resize(min_buffer_size + additional_buffer);
				assert(notifier);
				notifier->async_read_some(
					boost::asio::buffer(read_buffer),
					[this, receiver = std::forward<Observer>(receiver)](boost::system::error_code error, std::size_t bytes_read) mutable
				{
					if (error)
					{
						if (error == boost::asio::error::operation_aborted)
						{
							return;
						}
						throw std::logic_error("not implemented");
					}
					else
					{
						std::vector<file_notification> changes;
						for (std::size_t i = 0; i < bytes_read; )
						{
							inotify_event const &event = *reinterpret_cast<inotify_event const *>(read_buffer.data() + i);
							changes.emplace_back(file_notification{event.mask, path(event.name + 0, std::find(event.name + 0, event.name + event.len, '\0'))});
							i += sizeof(inotify_event);
							i += event.len;
						}
						std::forward<Observer>(receiver).got_element(std::move(changes));
					}
				});
			}

		private:

			std::unique_ptr<boost::asio::posix::stream_descriptor> notifier;
			std::vector<char> read_buffer;
		};
	}
}

#endif
<commit_msg>add watch descriptor to Linux file_notification<commit_after>#ifndef SILICIUM_REACTIVE_LINUX_INOTIFY_HPP
#define SILICIUM_REACTIVE_LINUX_INOTIFY_HPP

#include <silicium/observable/observer.hpp>
#include <silicium/error_or.hpp>
#include <silicium/exchange.hpp>
#include <silicium/linux/inotify_watch_descriptor.hpp>
#include <silicium/path.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <boost/swap.hpp>
#include <boost/optional.hpp>
#include <boost/ref.hpp>
#include <dirent.h>

namespace Si
{
	namespace linux
	{
		struct file_notification
		{
			boost::uint32_t mask;
			path name;
			int watch_descriptor;

			file_notification() BOOST_NOEXCEPT
			    : mask(0)
			    , watch_descriptor(-1)
			{
			}

			explicit file_notification(boost::uint32_t mask, path name, int watch_descriptor) BOOST_NOEXCEPT
			    : mask(mask)
			    , name(std::move(name))
			    , watch_descriptor(watch_descriptor)
			{
			}
		};

		struct inotify_observable
		{
			typedef std::vector<file_notification> element_type;

			inotify_observable() BOOST_NOEXCEPT
			{
			}

			explicit inotify_observable(boost::asio::io_service &io)
				: notifier(Si::make_unique<boost::asio::posix::stream_descriptor>(boost::ref(io)))
			{
				int fd = inotify_init();
				if (fd < 0)
				{
					throw boost::system::system_error(errno, boost::system::posix_category);
				}
				try
				{
					notifier->assign(fd);
				}
				catch (...)
				{
					close(fd);
					throw;
				}
			}

			error_or<watch_descriptor> watch(boost::filesystem::path const &target, boost::uint32_t mask) BOOST_NOEXCEPT
			{
				assert(notifier);
				int const wd = inotify_add_watch(notifier->native_handle(), target.c_str(), mask);
				if (wd < 0)
				{
					return boost::system::error_code(errno, boost::system::posix_category);
				}
				return watch_descriptor(notifier->native_handle(), wd);
			}

			template <class Observer>
			void async_get_one(Observer &&receiver)
			{
				std::size_t const min_buffer_size = sizeof(inotify_event) + NAME_MAX + 1;
				std::size_t const additional_buffer = 8192;
				read_buffer.resize(min_buffer_size + additional_buffer);
				assert(notifier);
				notifier->async_read_some(
					boost::asio::buffer(read_buffer),
					[this, receiver = std::forward<Observer>(receiver)](boost::system::error_code error, std::size_t bytes_read) mutable
				{
					if (error)
					{
						if (error == boost::asio::error::operation_aborted)
						{
							return;
						}
						throw std::logic_error("not implemented");
					}
					else
					{
						std::vector<file_notification> changes;
						for (std::size_t i = 0; i < bytes_read; )
						{
							inotify_event const &event = *reinterpret_cast<inotify_event const *>(read_buffer.data() + i);
							changes.emplace_back(file_notification{event.mask, path(event.name + 0, std::find(event.name + 0, event.name + event.len, '\0')), event.wd});
							i += sizeof(inotify_event);
							i += event.len;
						}
						std::forward<Observer>(receiver).got_element(std::move(changes));
					}
				});
			}

		private:

			std::unique_ptr<boost::asio::posix::stream_descriptor> notifier;
			std::vector<char> read_buffer;
		};
	}
}

#endif
<|endoftext|>


<commit_before>
#pragma once

#include <cassert>

#include "fixed_vector.hh"
#include "singly_linked_list.hh"

template<typename ELT>
class LinkedStack {
private:
  SinglyLinkedList<ELT> _elements;

public:
  LinkedStack() { }

  int size() { return _elements.length(); }
  bool is_empty() { return _elements.is_empty(); }

  ELT peek() {
    assert(!is_empty());
    return _elements.front();
  }

  void push(ELT e) { _elements.add_front(e); }

  void pop() {
    assert(!is_empty());
    _elements.remove_front();
  }
};

template<typename ELT>
class FixedStack {
private:
  FixedVector<ELT>* _elements;
  int _size;

public:
  FixedStack(int capacity) {
    assert(capacity > 0);
    _elements = new FixedVector<ELT>(capacity, ELT());
    _size = 0;
  }

  ~FixedStack() { delete _elements; }

  int size() { return _size; }
  bool is_empty() { return (0 == _size); }

  ELT peek() {
    assert(!is_empty());
    return _elements->get(_size - 1);
  }

  void push(ELT e) {
    assert(_size < _elements->length());
    _elements->set(_size, e);
    _size++;
  }

  void pop() {
    assert(!is_empty());
    _size--;
  }
};
<commit_msg>assert stack overflow condition<commit_after>
#pragma once

#include <cassert>

#include "fixed_vector.hh"
#include "singly_linked_list.hh"

template<typename ELT>
class LinkedStack {
private:
  // This is a very simple wrapper around SinglyLinkedList.
  SinglyLinkedList<ELT> _elements;

public:
  LinkedStack() { }

  int size() { return _elements.length(); }
  bool is_empty() { return _elements.is_empty(); }

  ELT peek() {
    assert(!is_empty());
    return _elements.front();
  }

  void push(ELT e) { _elements.add_front(e); }

  void pop() {
    assert(!is_empty());
    _elements.remove_front();
  }
};

template<typename ELT>
class FixedStack {
private:
  FixedVector<ELT>* _elements;
  int _size;

public:
  FixedStack(int capacity) {
    assert(capacity > 0);
    _elements = new FixedVector<ELT>(capacity, ELT());
    _size = 0;
  }

  ~FixedStack() { delete _elements; }

  int size() { return _size; }
  bool is_empty() { return (0 == _size); }

  int capacity() { return _elements->length(); }
  bool is_full() { return (_size == capacity()); }

  ELT peek() {
    assert(!is_empty());
    return _elements->get(_size - 1);
  }

  void push(ELT e) {
    assert(!is_full());
    _elements->set(_size, e);
    _size++;
  }

  void pop() {
    assert(!is_empty());
    _size--;
  }
};
<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//$Id$

#ifndef SOCKETIOTESTCOMPONENT_HPP_INCLUDED
#define SOCKETIOTESTCOMPONENT_HPP_INCLUDED

#include "ComponentEssentials.h"
#include "socketutility.h"
#include <iostream>

#define ACK 0x01
#define NACK 0x02

namespace hopsan {

    class SocketIOTestComponent : public ComponentSignal
    {
    private:
        HString mOtherIp, mOtherPort, mThisPort;
        SocketUtility mSocketUtility;
        int mMasterSlave, mRequireACK, mInitTimout, mSimTimout, mSleepUS;
        double *mpInput, *mpOutput;

    public:
        static Component *Creator()
        {
            return new SocketIOTestComponent();
        }

        void configure()
        {
            addConstant("other_ip", "The ip adress", "", "127.0.0.1", mOtherIp);
            addConstant("other_port", "Write port", "", "30000", mOtherPort);
            addConstant("this_port", "Read port", "", "30001", mThisPort);
            std::vector<HString> conds;
            conds.push_back("Master");
            conds.push_back("Slave");
            addConditionalConstant("masl", "Master or Slave", conds, mMasterSlave);
            conds.clear();
            conds.push_back("True");
            conds.push_back("False");
            addConditionalConstant("requireAck", "Require or Send ACK", conds, mRequireACK);
            addConstant("initTimeout", "The timeout during initialization", "ms", 5000, mInitTimout);
            addConstant("simTimeout", "The timeout during simulation", "ms", 1000, mSimTimout);
            addConstant("timeoutSleep", "The timeout wait sleep", "us", -1, mSleepUS);

            addInputVariable("in", "Value input", "", 0, &mpInput);
            addOutputVariable("out", "Value input", "", &mpOutput);

            addReadPort("sortIn", "NodeSignal", "Sorting port, value has no effect", Port::NotRequired);
            addWritePort("sortOut", "NodeSignal", "Sorting port, value has no effect", Port::NotRequired);
        }

        bool preInitialize()
        {
            mSocketUtility.setSleepUS(mSleepUS);
            if (!mSocketUtility.openSocket(mOtherIp.c_str(), mOtherPort.c_str(), mThisPort.c_str()))
            {
                addErrorMessage(mSocketUtility.getErrorString().c_str());
                return false;
            }
            return true;
        }

        void initialize()
        {
            // Master
            if (mMasterSlave == 0)
            {
                // Write init message
                if (mSocketUtility.writeSocket("Initialize") == 0)
                {
                    addErrorMessage(mSocketUtility.getErrorString().c_str());
                }

                // Wait for ACK or NACK
                char ack;
                if (mSocketUtility.readSocket(ack, mInitTimout) == 0)
                {
                    addWarningMessage(HString("Failed to read ACK! ")+mSocketUtility.getErrorString().c_str());
                }
                if ( (mRequireACK == 0) && (ack != ACK) )
                {
                    stopSimulation();
                    return;
                }

            }
            // Slave
            else if (mMasterSlave == 1)
            {
                // Wait for startup message
                std::string input;
                if (mSocketUtility.readSocket(input, 10, mInitTimout) == 0)
                {
                    addWarningMessage(HString("Failed to read startup message! "));
                }

                // Send ACK or NACK
                if (input == "Initialize" && mRequireACK == 0 )
                {
                    if (mSocketUtility.writeSocket(char(ACK)) == 0)
                    {
                        addErrorMessage(mSocketUtility.getErrorString().c_str());
                    }
                }
            }
        }

        void simulateOneTimestep()
        {
            // Master
            if (mMasterSlave == 0)
            {
                // Write input to socket
                if (mSocketUtility.writeSocket(*mpInput) == 0)
                {
                    addErrorMessage(mSocketUtility.getErrorString().c_str());
                }

                // Wait for ack
                if (mRequireACK == 0)
                {
                    char ack;
                    if (mSocketUtility.readSocket(ack, mSimTimout) == 0 || ack != ACK )
                    {
                        addErrorMessage(HString("Failed to read ACK message! ")+mSocketUtility.getErrorString().c_str());
                        stopSimulation();
                        return;
                    }
                }
            }
            // Slave
            else if (mMasterSlave == 1)
            {
                // Read input from socket
                if (mSocketUtility.readSocket(*mpOutput, mSimTimout) == 0)
                {
                    addWarningMessage(HString("Failed to read double from socket before timeout!"));
                    stopSimulation();
                    return;
                }

                // Send ACK or NACK
                if (mRequireACK == 0)
                {
                    if (mSocketUtility.writeSocket(char(ACK)) == 0)
                    {
                        addErrorMessage(mSocketUtility.getErrorString().c_str());
                    }
                }
            }
        }

        void finalize()
        {
            mSocketUtility.closeSocket();
        }

        bool isExperimental() const
        {
            return true;
        }
    };
}

#endif
<commit_msg>Send and receive for both master and slave<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//$Id$

#ifndef SOCKETIOTESTCOMPONENT_HPP_INCLUDED
#define SOCKETIOTESTCOMPONENT_HPP_INCLUDED

#include "ComponentEssentials.h"
#include "ComponentUtilities.h"
#include "socketutility.h"
#include <iostream>

#define ACK 0x01
#define NACK 0x02

namespace hopsan {

    class SocketIOTestComponent : public ComponentSignal
    {
    private:
        HString mOtherIp, mOtherPort, mThisPort;
        SocketUtility mSocketUtility;
        int mMasterSlave, mRequireACK, mInitTimout, mSimAckTimout, mSimReciveTimout, mSleepUS;
        double *mpInput, *mpOutput;
        Port *pInPort, *pOutPort;

        bool readACK(int timeout)
        {
            char ack;
            if (mSocketUtility.readSocket(ack, timeout) == 0)
            {
                addErrorMessage(HString("Failed to read ACK message before timeout! ")+mSocketUtility.getErrorString().c_str());
                return false;
            }
            if (ack != ACK)
            {
                addWarningMessage(HString("Did not receive ACK got: ")+to_hstring(ack));
                return false;
            }
            return true;
        }

        bool sendACKmsg(char msg)
        {
            if (mSocketUtility.writeSocket(msg) == 0)
            {
                addErrorMessage(mSocketUtility.getErrorString().c_str());
                return false;
            }
            return true;
        }

    public:
        static Component *Creator()
        {
            return new SocketIOTestComponent();
        }

        void configure()
        {
            addConstant("other_ip", "The ip adress", "", "127.0.0.1", mOtherIp);
            addConstant("other_port", "Write port", "", "30000", mOtherPort);
            addConstant("this_port", "Read port", "", "30001", mThisPort);
            std::vector<HString> conds;
            conds.push_back("Master");
            conds.push_back("Slave");
            addConditionalConstant("masl", "Master or Slave", conds, mMasterSlave);
            conds.clear();
            conds.push_back("True");
            conds.push_back("False");
            addConditionalConstant("requireAck", "Require or Send ACK", conds, mRequireACK);
            addConstant("initTimeout", "The timeout during initialization", "ms", 5000, mInitTimout);
            addConstant("simAckTimeout", "The ack timeout during simulation", "ms", 1000, mSimAckTimout);
            addConstant("simRecTimeout", "The receive timeout during simulation", "ms", 1000, mSimReciveTimout);
            addConstant("timeoutSleep", "The timeout wait sleep", "us", -1, mSleepUS);

            pInPort = addInputVariable("in", "Value input", "", 0, &mpInput);
            pOutPort = addOutputVariable("out", "Value input", "", &mpOutput);

            addReadPort("sortIn", "NodeSignal", "Sorting port, value has no effect", Port::NotRequired);
            addWritePort("sortOut", "NodeSignal", "Sorting port, value has no effect", Port::NotRequired);
        }

        bool preInitialize()
        {
            mSocketUtility.setSleepUS(mSleepUS);
            if (!mSocketUtility.openSocket(mOtherIp.c_str(), mOtherPort.c_str(), mThisPort.c_str()))
            {
                addErrorMessage(mSocketUtility.getErrorString().c_str());
                return false;
            }
            return true;
        }

        void initialize()
        {
            // Master
            if (mMasterSlave == 0)
            {
                // Write init message
                if (mSocketUtility.writeSocket("Initialize") == 0)
                {
                    addErrorMessage(mSocketUtility.getErrorString().c_str());
                }

                // Wait for ACK or NACK
                if (mRequireACK == 0)
                {
                    if (!readACK(mInitTimout))
                    {
                        stopSimulation();
                        return;
                    }
                }
            }
            // Slave
            else if (mMasterSlave == 1)
            {
                // Wait for startup message
                std::string input;
                if (mSocketUtility.readSocket(input, 10, mInitTimout) == 0)
                {
                    addWarningMessage(HString("Failed to read startup message! "));
                }

                // Send ACK or NACK
                if (mRequireACK == 0)
                {
                    if (input == "Initialize")
                    {
                        if (!sendACKmsg(ACK))
                        {
                            stopSimulation();
                            return;
                        }
                    }
                    else
                    {
                        if (!sendACKmsg(NACK))
                        {
                            stopSimulation();
                            return;
                        }
                    }
                }
            }
        }

        void simulateOneTimestep()
        {
            // Master
            if (mMasterSlave == 0)
            {
                // Write input to socket
                if (mSocketUtility.writeSocket(*mpInput) == 0)
                {
                    addErrorMessage(mSocketUtility.getErrorString().c_str());
                }

                // Wait for ack
                if (mRequireACK == 0)
                {
                    if (!readACK(mSimAckTimout))
                    {
                        stopSimulation();
                        return;
                    }
                }

                // Wait for return message
                double tmp;
                if (mSocketUtility.readSocket(tmp, mSimReciveTimout))
                {
                    *mpOutput = tmp;
                }
            }
            // Slave
            else if (mMasterSlave == 1)
            {
                // Read input from socket
                if (mSocketUtility.readSocket(*mpOutput, mSimReciveTimout) == 0)
                {
                    addWarningMessage(HString("Failed to read double from socket before timeout!"));
                    stopSimulation();
                    return;
                }

                // Send ACK or NACK
                if (mRequireACK == 0)
                {
                    if (!sendACKmsg(ACK))
                    {
                        stopSimulation();
                        return;
                    }
                }

                // Write to socket
                if (mSocketUtility.writeSocket(*mpInput) == 0)
                {
                    addErrorMessage(mSocketUtility.getErrorString().c_str());
                }
            }
        }

        void finalize()
        {
            mSocketUtility.closeSocket();
        }

        bool isExperimental() const
        {
            return true;
        }
    };
}

#endif
<|endoftext|>


<commit_before>#include <nan.h>
#include <v8-profiler.h>
#include <stdlib.h>
#if defined(_WIN32)
  #include <time.h>
  #define snprintf _snprintf
#else
  #include <sys/time.h>
#endif

using namespace v8;

char filename[256];
bool addTimestamp;

class FileOutputStream: public OutputStream {
  public:
    FileOutputStream(FILE* stream): stream_(stream) { }
    virtual int GetChunkSize() {
      return 65536;
    }
    virtual void EndOfStream() { }
    virtual WriteResult WriteAsciiChunk(char* data, int size) {
      const size_t len = static_cast<size_t>(size);
      size_t off = 0;
      while (off < len && !feof(stream_) && !ferror(stream_))
        off += fwrite(data + off, 1, len - off, stream_);
      return off == len ? kContinue : kAbort;
    }

  private:
    FILE* stream_;
};

void OnOOMError(const char *location, bool is_heap_oom) {
  if (addTimestamp) {
    // Add timestamp to filename
    time_t rawtime;
    struct tm* timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);

    char * pch;
    pch = strstr (filename,".heapsnapshot");
    strncpy (pch,"",1);
    strcat (filename, "-%Y%m%dT%H%M%S.heapsnapshot");

    char newFilename[256];
    strftime(newFilename, sizeof(filename), filename, timeinfo);
    strcpy(filename, newFilename);
  }

  fprintf(stderr, "Generating Heapdump to '%s' now...\n", filename);
  FILE* fp = fopen(filename, "w");
  if (fp == NULL) abort();

  // Create heapdump, depending on which Node.js version this can differ
  // for now, just support Node.js 7 and higher
  const HeapSnapshot* snap = v8::Isolate::GetCurrent()->GetHeapProfiler()->TakeHeapSnapshot();

  FileOutputStream stream(fp);
  snap->Serialize(&stream, HeapSnapshot::kJSON);
  fclose(fp);

  fprintf(stderr, "Done! Exiting process now.\n");
  exit(1);
}

void ParseArgumentsAndSetErrorHandler(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  isolate->SetOOMErrorHandler(OnOOMError);

  // parse JS arguments
  // 1: filename
  // 2: addTimestamp boolean
  String::Utf8Value fArg(isolate, args[0]->ToString());
  strncpy(filename, (const char*)(*fArg), sizeof(filename) - 1);
  addTimestamp = args[1]->BooleanValue();
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "call", ParseArgumentsAndSetErrorHandler);
}

NODE_MODULE(NODE_OOM_HEAPDUMP_NATIVE, init)<commit_msg>* Fix code to work in Nodejs 7 using conditional statements<commit_after>#include <nan.h>
#include <v8-profiler.h>
#include <stdlib.h>
#if defined(_WIN32)
  #include <time.h>
  #define snprintf _snprintf
#else
  #include <sys/time.h>
#endif

using namespace v8;

char filename[256];
bool addTimestamp;

class FileOutputStream: public OutputStream {
  public:
    FileOutputStream(FILE* stream): stream_(stream) { }
    virtual int GetChunkSize() {
      return 65536;
    }
    virtual void EndOfStream() { }
    virtual WriteResult WriteAsciiChunk(char* data, int size) {
      const size_t len = static_cast<size_t>(size);
      size_t off = 0;
      while (off < len && !feof(stream_) && !ferror(stream_))
        off += fwrite(data + off, 1, len - off, stream_);
      return off == len ? kContinue : kAbort;
    }

  private:
    FILE* stream_;
};

void OnOOMError(const char *location, bool is_heap_oom) {
  if (addTimestamp) {
    // Add timestamp to filename
    time_t rawtime;
    struct tm* timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);

    char * pch;
    pch = strstr (filename,".heapsnapshot");
    strncpy (pch,"",1);
    strcat (filename, "-%Y%m%dT%H%M%S.heapsnapshot");

    char newFilename[256];
    strftime(newFilename, sizeof(filename), filename, timeinfo);
    strcpy(filename, newFilename);
  }

  fprintf(stderr, "Generating Heapdump to '%s' now...\n", filename);
  FILE* fp = fopen(filename, "w");
  if (fp == NULL) abort();

  // Create heapdump, depending on which Node.js version this can differ
  // for now, just support Node.js 7 and higher
  const HeapSnapshot* snap = v8::Isolate::GetCurrent()->GetHeapProfiler()->TakeHeapSnapshot();

  FileOutputStream stream(fp);
  snap->Serialize(&stream, HeapSnapshot::kJSON);
  fclose(fp);

  fprintf(stderr, "Done! Exiting process now.\n");
  exit(1);
}

void ParseArgumentsAndSetErrorHandler(const FunctionCallbackInfo<Value>& args) {
  Isolate* isolate = args.GetIsolate();
  isolate->SetOOMErrorHandler(OnOOMError);

  // parse JS arguments
  // 1: filename
  // 2: addTimestamp boolean
  #if NODE_VERSION_AT_LEAST(9, 0, 0)
  String::Utf8Value fArg(isolate, args[0]->ToString());
  #else
  String::Utf8Value fArg(args[0]->ToString());
  #endif
  strncpy(filename, (const char*)(*fArg), sizeof(filename) - 1);

  addTimestamp = args[1]->BooleanValue();
}

void init(Local<Object> exports) {
  NODE_SET_METHOD(exports, "call", ParseArgumentsAndSetErrorHandler);
}

NODE_MODULE(NODE_OOM_HEAPDUMP_NATIVE, init)<|endoftext|>


<commit_before>#include "kegboard.h"
#include "KegboardPacket.h"
#include <avr/io.h>
#include <string.h>
#include <util/crc16.h>

KegboardPacket::KegboardPacket()
{
  Reset();
}

bool KegboardPacket::IsReset() {
  return (m_type == 0) && (m_len == 0);
}

void KegboardPacket::Reset()
{
  m_len = 0;
  m_type = 0;
}

void KegboardPacket::AddTag(uint8_t tag, uint8_t buflen, char *buf)
{
  int i=0;
  m_payload[m_len++] = tag;
  m_payload[m_len++] = buflen;
  while (i < buflen && m_len < KBSP_PAYLOAD_MAXLEN) {
    m_payload[m_len++] = (uint8_t) (*(buf+i));
    i++;
  }
}

uint8_t* KegboardPacket::FindTag(uint8_t tagnum) {
  uint8_t pos=0;
  while (pos < m_len && pos < KBSP_PAYLOAD_MAXLEN) {
    uint8_t tag = m_payload[pos];
    if (tag == tagnum) {
      return m_payload+pos;
    }
    pos += 2 + m_payload[pos+1];
  }
  return NULL;
}

bool KegboardPacket::ReadTag(uint8_t tagnum, uint8_t *value) {
  uint8_t *offptr = FindTag(tagnum);
  if (offptr == NULL) {
    return false;
  }
  *value = *(offptr+2);
  return true;
}

bool KegboardPacket::ReadTag(uint8_t tagnum, uint8_t** value) {
  uint8_t *offptr = FindTag(tagnum);
  if (offptr == NULL) {
    return false;
  }
  uint8_t slen = *(offptr+1);
  memcpy(*value, (offptr+2), slen);
  return true;
}

void KegboardPacket::AppendBytes(char *buf, int buflen)
{
  int i=0;
  while (i < buflen && m_len < KBSP_PAYLOAD_MAXLEN) {
    m_payload[m_len++] = (uint8_t) (*(buf+i));
    i++;
  }
}

uint16_t KegboardPacket::GenCrc()
{
  uint16_t crc = KBSP_PREFIX_CRC;

  crc = _crc_ccitt_update(crc, m_type & 0xff);
  crc = _crc_ccitt_update(crc, (m_type >> 8) & 0xff);
  crc = _crc_ccitt_update(crc, m_len & 0xff);
  crc = _crc_ccitt_update(crc, (m_len >> 8) & 0xff);

  for (int i=0; i<m_len; i++) {
    crc = _crc_ccitt_update(crc, m_payload[i]);
  }

  return crc;
}

void KegboardPacket::Print()
{
  int i;
  // header
  // header: prefix
  Serial.print(KBSP_PREFIX);

  // header: message_id
  Serial.print(m_type & 0xff, BYTE);
  Serial.print((m_type >> 8) & 0xff, BYTE);
  // header: payload_len
  Serial.print(m_len & 0xff, BYTE);
  Serial.print((m_len >> 8) & 0xff, BYTE);

  // payload
  for (i=0; i<m_len; i++) {
    Serial.print(m_payload[i], BYTE);
  }

  // trailer
  uint16_t crc = GenCrc();
  Serial.print(crc & 0xff, BYTE);
  Serial.print((crc >> 8) & 0xff, BYTE);
  Serial.print('\r', BYTE);
  Serial.print('\n', BYTE);
}
<commit_msg>Small optimizations.<commit_after>#include "kegboard.h"
#include "KegboardPacket.h"
#include <avr/io.h>
#include <string.h>
#include <util/crc16.h>

static uint16_t crc_ccitt_update_int(uint16_t crc, int value) {
  crc = _crc_ccitt_update(crc, value & 0xff);
  return _crc_ccitt_update(crc, (value >> 8) & 0xff);
}

static void serial_print_int(int value) {
  Serial.print(value & 0xff, BYTE);
  Serial.print((value >> 8) & 0xff, BYTE);
}

KegboardPacket::KegboardPacket()
{
  Reset();
}

bool KegboardPacket::IsReset() {
  return (m_type == 0) && (m_len == 0);
}

void KegboardPacket::Reset()
{
  m_len = 0;
  m_type = 0;
}

void KegboardPacket::AddTag(uint8_t tag, uint8_t buflen, char *buf)
{
  int i=0;
  m_payload[m_len++] = tag;
  m_payload[m_len++] = buflen;
  AppendBytes(buf+2, buflen);
}

uint8_t* KegboardPacket::FindTag(uint8_t tagnum) {
  uint8_t pos=0;
  while (pos < m_len && pos < KBSP_PAYLOAD_MAXLEN) {
    uint8_t tag = m_payload[pos];
    if (tag == tagnum) {
      return m_payload+pos;
    }
    pos += 2 + m_payload[pos+1];
  }
  return NULL;
}

bool KegboardPacket::ReadTag(uint8_t tagnum, uint8_t *value) {
  uint8_t *offptr = FindTag(tagnum);
  if (offptr == NULL) {
    return false;
  }
  *value = *(offptr+2);
  return true;
}

bool KegboardPacket::ReadTag(uint8_t tagnum, uint8_t** value) {
  uint8_t *offptr = FindTag(tagnum);
  if (offptr == NULL) {
    return false;
  }
  uint8_t slen = *(offptr+1);
  memcpy(*value, (offptr+2), slen);
  return true;
}

void KegboardPacket::AppendBytes(char *buf, int buflen)
{
  int i=0;
  while (i < buflen && m_len < KBSP_PAYLOAD_MAXLEN) {
    m_payload[m_len++] = (uint8_t) (*(buf+i));
    i++;
  }
}

uint16_t KegboardPacket::GenCrc()
{
  uint16_t crc = KBSP_PREFIX_CRC;

  crc = crc_ccitt_update_int(crc, m_type);
  crc = crc_ccitt_update_int(crc, m_len);

  for (int i=0; i<m_len; i++) {
    crc = _crc_ccitt_update(crc, m_payload[i]);
  }

  return crc;
}

void KegboardPacket::Print()
{
  int i;
  uint16_t crc = KBSP_PREFIX_CRC;

  // header
  // header: prefix
  Serial.print(KBSP_PREFIX);

  // header: message_id
  serial_print_int(m_type);
  crc = crc_ccitt_update_int(crc, m_type);

  // header: payload_len
  serial_print_int(m_len);
  crc = crc_ccitt_update_int(crc, m_len);

  // payload
  for (i=0; i<m_len; i++) {
    Serial.print(m_payload[i], BYTE);
    crc = _crc_ccitt_update(crc, m_payload[i]);
  }

  // trailer
  serial_print_int(crc);
  Serial.print('\r', BYTE);
  Serial.print('\n', BYTE);
}
<|endoftext|>


<commit_before>// Martin Meliss   :
//

#include "stdafx.h"
#include <iostream>
#include <wchar.h>

#include "Pin.h"

int _tmain(int argc, _TCHAR* argv[])
{
	CPin pin;

	int iPinCount = pin.GetPinCount();

	int pValidResponse[] = { 0, 1, 2, 3, 4, 10, 11, 12, 13, 20, 21, 22, 30, 40 };

	while (iPinCount > 1)
	{
		sPin currPIN = pin.GetRandom();
		std::cout << "Now PIN count: " << iPinCount << std::endl;
		std::cout << "Try enter PIN: " << currPIN.a1 << currPIN.a2 << currPIN.a3 << currPIN.a4 << std::endl;

		int iResponse = -1;
		while (iResponse == -1)
		{
			std::cout << "Enter response: ";
			std::cin >> iResponse;
			if (std::cin.fail())
			{
				std::cin.clear();
				char c;
				std::cin >> c;
			}
			std::cout << std::endl;
			bool bGoodResponse = false;
			for (int i = 0, iEnd = sizeof(pValidResponse) >> 2; i < iEnd; i++)
			{
				if (iResponse == pValidResponse[i])
				{
					bGoodResponse = true;
					break;
				}
			}
			if (!bGoodResponse)
			{
				iResponse = -1;
				std::cout << "Response is not valid!" << std::endl;
			}
		}
		iPinCount = pin.SiftPins(iResponse, currPIN);
	}

	sPin currPIN = pin.GetRandom();
	std::cout << "Secret PIN is: " << currPIN.a1 << currPIN.a2 << currPIN.a3 << currPIN.a4 << std::endl;
	std::cout << "Done!" << std::endl << "enter any key" << std::endl;

	_getwch();

	return 0;
}

<commit_msg>Delete DigitalLock.cpp<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "copasi/utilities/CUnitDefinitionDB.h"
#include "utilities/CCopasiMessage.h"

//CCopasiVectorN(const std::string & name = "NoName",
//               const CCopasiContainer * pParent = NULL):

CUnitDefinitionDB::CUnitDefinitionDB(const std::string & name,
                                     const CCopasiContainer * pParent):
  CCopasiVectorN(name, pParent),
  mSymbolToUnitDefinitions()
{
}

//virtual
bool CUnitDefinitionDB::add(const CUnitDefinition & src)
{
  // This form will construct a copy, before adding (inherited
  // from CCopasiVectorN). When the CUnitDefinition
  // copy constructor is called, an exception will be thrown if
  // the symbol is already in use.
  CCopasiVectorN::add(src);
  mSymbolToUnitDefinitions[src.getSymbol()] = mRecentElement;

  return true;
}

//virtual
bool CUnitDefinitionDB::add(CUnitDefinition * src, bool adopt)
{

  // If it's symbol is already present, this form will not add
  // a pointer to the src object, and will return false.
  bool success = false;

  if (containsSymbol(src->getSymbol()))
    success = false;
  else
    {
      CCopasiVectorN::add(src, adopt);
      mSymbolToUnitDefinitions[src->getSymbol()] = mRecentElement;
      success = true;
    }

  return success;
}

//virtual
void CUnitDefinitionDB::remove(const size_t & index)
{
  mSymbolToUnitDefinitions.erase(operator [](index)->getSymbol());
  CCopasiVector::remove(index);
}

//virtual
bool CUnitDefinitionDB::remove(CUnitDefinition * unitDef)
{
  mSymbolToUnitDefinitions.erase(unitDef->getSymbol());
  CCopasiVector::remove(unitDef);
}

//virtual
void CUnitDefinitionDB::remove(const std::string & name)
{
  mSymbolToUnitDefinitions.erase(operator [](name)->getSymbol());
  CCopasiVectorN::remove(name);
}

bool CUnitDefinitionDB::containsSymbol(std::string symbol)
{
  if (mSymbolToUnitDefinitions.count(symbol))
    return true;
  else
    return false;
}

const CUnitDefinition * CUnitDefinitionDB::getUnitDefFromSymbol(std::string symbol)
{
  std::map<std::string, CUnitDefinition *>::const_iterator found = mSymbolToUnitDefinitions.find(symbol);

  if (found != mSymbolToUnitDefinitions.end())
    {
      return found->second;
    }

  return NULL;
}
<commit_msg>- fix compilation on windows<commit_after>// Copyright (C) 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

#include "copasi/utilities/CUnitDefinitionDB.h"
#include "utilities/CCopasiMessage.h"

//CCopasiVectorN(const std::string & name = "NoName",
//               const CCopasiContainer * pParent = NULL):

CUnitDefinitionDB::CUnitDefinitionDB(const std::string & name,
                                     const CCopasiContainer * pParent):
  CCopasiVectorN(name, pParent),
  mSymbolToUnitDefinitions()
{
}

//virtual
bool CUnitDefinitionDB::add(const CUnitDefinition & src)
{
  // This form will construct a copy, before adding (inherited
  // from CCopasiVectorN). When the CUnitDefinition
  // copy constructor is called, an exception will be thrown if
  // the symbol is already in use.
  CCopasiVectorN::add(src);
  mSymbolToUnitDefinitions[src.getSymbol()] = mRecentElement;

  return true;
}

//virtual
bool CUnitDefinitionDB::add(CUnitDefinition * src, bool adopt)
{

  // If it's symbol is already present, this form will not add
  // a pointer to the src object, and will return false.
  bool success = false;

  if (containsSymbol(src->getSymbol()))
    success = false;
  else
    {
      CCopasiVectorN::add(src, adopt);
      mSymbolToUnitDefinitions[src->getSymbol()] = mRecentElement;
      success = true;
    }

  return success;
}

//virtual
void CUnitDefinitionDB::remove(const size_t & index)
{
  mSymbolToUnitDefinitions.erase(operator [](index)->getSymbol());
  CCopasiVector::remove(index);
}

//virtual
bool CUnitDefinitionDB::remove(CUnitDefinition * unitDef)
{
  mSymbolToUnitDefinitions.erase(unitDef->getSymbol());
  return CCopasiVector::remove(unitDef);
}

//virtual
void CUnitDefinitionDB::remove(const std::string & name)
{
  mSymbolToUnitDefinitions.erase(operator [](name)->getSymbol());
  CCopasiVectorN::remove(name);
}

bool CUnitDefinitionDB::containsSymbol(std::string symbol)
{
  if (mSymbolToUnitDefinitions.count(symbol))
    return true;
  else
    return false;
}

const CUnitDefinition * CUnitDefinitionDB::getUnitDefFromSymbol(std::string symbol)
{
  std::map<std::string, CUnitDefinition *>::const_iterator found = mSymbolToUnitDefinitions.find(symbol);

  if (found != mSymbolToUnitDefinitions.end())
    {
      return found->second;
    }

  return NULL;
}
<|endoftext|>


<commit_before>/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#ifdef __osf__
#  define _OSF_SOURCE
#  define _POSIX_C_SOURCE 199506L
#  define _XOPEN_SOURCE_EXTENDED
#endif

#include "kwsysPrivate.h"
#include KWSYS_HEADER(Encoding.hxx)
#include KWSYS_HEADER(Encoding.h)
#include KWSYS_HEADER(stl/vector)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "Encoding.hxx.in"
# include "Encoding.h.in"
#endif

#include <stdlib.h>
#include <string.h>

#ifdef _MSC_VER
# pragma warning (disable: 4786)
#endif

// Windows API.
#if defined(_WIN32)
# include <windows.h>
#endif

namespace KWSYS_NAMESPACE
{

Encoding::CommandLineArguments
Encoding::CommandLineArguments::Main(int argc, char const* const* argv)
{
#ifdef _WIN32
  (void) argc;
  (void) argv;

  int ac;
  LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac);

  std::vector<std::string> av1(ac);
  std::vector<char const*> av2(ac);
  for(int i=0; i<ac; i++)
    {
    av1[i] = ToNarrow(w_av[i]);
    av2[i] = av1[i].c_str();
    }
  LocalFree(w_av);
  return CommandLineArguments(ac, &av2[0]);
#else
  return CommandLineArguments(argc, argv);
#endif
}

Encoding::CommandLineArguments::CommandLineArguments(int ac,
                                                     char const* const* av)
{
  this->argv_.resize(ac+1);
  for(int i=0; i<ac; i++)
    {
    this->argv_[i] = strdup(av[i]);
    }
  this->argv_[ac] = 0;
}

Encoding::CommandLineArguments::CommandLineArguments(int ac,
                                                     wchar_t const* const* av)
{
  this->argv_.resize(ac+1);
  for(int i=0; i<ac; i++)
    {
    this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]);
    }
  this->argv_[ac] = 0;
}

Encoding::CommandLineArguments::~CommandLineArguments()
{
  for(size_t i=0; i<this->argv_.size(); i++)
    {
    free(argv_[i]);
    }
}

Encoding::CommandLineArguments::
  CommandLineArguments(const CommandLineArguments& other)
{
  this->argv_.resize(other.argv_.size());
  for(size_t i=0; i<this->argv_.size(); i++)
    {
    this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
    }
}

Encoding::CommandLineArguments&
Encoding::CommandLineArguments::operator=(const CommandLineArguments& other)
{
  size_t i;
  for(i=0; i<this->argv_.size(); i++)
    {
    free(this->argv_[i]);
    }

  this->argv_.resize(other.argv_.size());
  for(i=0; i<this->argv_.size(); i++)
    {
    this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
    }

  return *this;
}

int Encoding::CommandLineArguments::argc() const
{
  return static_cast<int>(this->argv_.size() - 1);
}

char const* const* Encoding::CommandLineArguments::argv() const
{
  return &this->argv_[0];
}

#if KWSYS_STL_HAS_WSTRING

kwsys_stl::wstring Encoding::ToWide(const kwsys_stl::string& str)
{
  return ToWide(str.c_str());
}

kwsys_stl::string Encoding::ToNarrow(const kwsys_stl::wstring& str)
{
  return ToNarrow(str.c_str());
}

kwsys_stl::wstring Encoding::ToWide(const char* cstr)
{
  kwsys_stl::wstring wstr;
  size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1;
  if(length > 0)
    {
    kwsys_stl::vector<wchar_t> wchars(length);
    if(kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0)
      {
      wstr = &wchars[0];
      }
    }
  return wstr;
}

kwsys_stl::string Encoding::ToNarrow(const wchar_t* wcstr)
{
  kwsys_stl::string str;
  size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1;
  if(length > 0)
    {
    std::vector<char> chars(length);
    if(kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0)
      {
      str = &chars[0];
      }
    }
  return str;
}
#endif // KWSYS_STL_HAS_WSTRING

} // namespace KWSYS_NAMESPACE
<commit_msg>Encoding: Add self-assignment check to CommandLineArguments<commit_after>/*============================================================================
  KWSys - Kitware System Library
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/

#ifdef __osf__
#  define _OSF_SOURCE
#  define _POSIX_C_SOURCE 199506L
#  define _XOPEN_SOURCE_EXTENDED
#endif

#include "kwsysPrivate.h"
#include KWSYS_HEADER(Encoding.hxx)
#include KWSYS_HEADER(Encoding.h)
#include KWSYS_HEADER(stl/vector)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
# include "Encoding.hxx.in"
# include "Encoding.h.in"
#endif

#include <stdlib.h>
#include <string.h>

#ifdef _MSC_VER
# pragma warning (disable: 4786)
#endif

// Windows API.
#if defined(_WIN32)
# include <windows.h>
#endif

namespace KWSYS_NAMESPACE
{

Encoding::CommandLineArguments
Encoding::CommandLineArguments::Main(int argc, char const* const* argv)
{
#ifdef _WIN32
  (void) argc;
  (void) argv;

  int ac;
  LPWSTR* w_av = CommandLineToArgvW(GetCommandLineW(), &ac);

  std::vector<std::string> av1(ac);
  std::vector<char const*> av2(ac);
  for(int i=0; i<ac; i++)
    {
    av1[i] = ToNarrow(w_av[i]);
    av2[i] = av1[i].c_str();
    }
  LocalFree(w_av);
  return CommandLineArguments(ac, &av2[0]);
#else
  return CommandLineArguments(argc, argv);
#endif
}

Encoding::CommandLineArguments::CommandLineArguments(int ac,
                                                     char const* const* av)
{
  this->argv_.resize(ac+1);
  for(int i=0; i<ac; i++)
    {
    this->argv_[i] = strdup(av[i]);
    }
  this->argv_[ac] = 0;
}

Encoding::CommandLineArguments::CommandLineArguments(int ac,
                                                     wchar_t const* const* av)
{
  this->argv_.resize(ac+1);
  for(int i=0; i<ac; i++)
    {
    this->argv_[i] = kwsysEncoding_DupToNarrow(av[i]);
    }
  this->argv_[ac] = 0;
}

Encoding::CommandLineArguments::~CommandLineArguments()
{
  for(size_t i=0; i<this->argv_.size(); i++)
    {
    free(argv_[i]);
    }
}

Encoding::CommandLineArguments::
  CommandLineArguments(const CommandLineArguments& other)
{
  this->argv_.resize(other.argv_.size());
  for(size_t i=0; i<this->argv_.size(); i++)
    {
    this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
    }
}

Encoding::CommandLineArguments&
Encoding::CommandLineArguments::operator=(const CommandLineArguments& other)
{
  if(this != &other)
    {
    size_t i;
    for(i=0; i<this->argv_.size(); i++)
      {
      free(this->argv_[i]);
      }

    this->argv_.resize(other.argv_.size());
    for(i=0; i<this->argv_.size(); i++)
      {
      this->argv_[i] = other.argv_[i] ? strdup(other.argv_[i]) : 0;
      }
    }

  return *this;
}

int Encoding::CommandLineArguments::argc() const
{
  return static_cast<int>(this->argv_.size() - 1);
}

char const* const* Encoding::CommandLineArguments::argv() const
{
  return &this->argv_[0];
}

#if KWSYS_STL_HAS_WSTRING

kwsys_stl::wstring Encoding::ToWide(const kwsys_stl::string& str)
{
  return ToWide(str.c_str());
}

kwsys_stl::string Encoding::ToNarrow(const kwsys_stl::wstring& str)
{
  return ToNarrow(str.c_str());
}

kwsys_stl::wstring Encoding::ToWide(const char* cstr)
{
  kwsys_stl::wstring wstr;
  size_t length = kwsysEncoding_mbstowcs(0, cstr, 0) + 1;
  if(length > 0)
    {
    kwsys_stl::vector<wchar_t> wchars(length);
    if(kwsysEncoding_mbstowcs(&wchars[0], cstr, length) > 0)
      {
      wstr = &wchars[0];
      }
    }
  return wstr;
}

kwsys_stl::string Encoding::ToNarrow(const wchar_t* wcstr)
{
  kwsys_stl::string str;
  size_t length = kwsysEncoding_wcstombs(0, wcstr, 0) + 1;
  if(length > 0)
    {
    std::vector<char> chars(length);
    if(kwsysEncoding_wcstombs(&chars[0], wcstr, length) > 0)
      {
      str = &chars[0];
      }
    }
  return str;
}
#endif // KWSYS_STL_HAS_WSTRING

} // namespace KWSYS_NAMESPACE
<|endoftext|>


<commit_before>/** \file    populate_in_tuebingen_available.cc
 *  \author  Dr. Johannes Ruscheinski
 *
 *  A tool that adds a new "SIG" field to a MARC record if there are UB or IFK call numbers in a record.
 */

/*
    Copyright (C) 2015, Library of the University of Tübingen

    This program 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.

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

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <cstdlib>
#include "DirectoryEntry.h"
#include "Leader.h"
#include "MarcUtil.h"
#include "StringUtil.h"
#include "Subfields.h"
#include "util.h"

void Usage() {
    std::cerr << "Usage: " << progname << " [--verbose] marc_input marc_output\n";
    std::exit(EXIT_FAILURE);
}

static FILE *output_ptr;
static unsigned modified_record_count;
static unsigned add_sig_count;

bool ProcessRecord(std::shared_ptr <Leader> &leader, std::vector <DirectoryEntry> * const dir_entries,
                   std::vector <std::string> * const field_data, std::string * const /*err_msg*/) {
    std::vector <std::pair<size_t, size_t>> local_block_boundaries;
    MarcUtil::FindAllLocalDataBlocks(*dir_entries, *field_data, &local_block_boundaries);

    bool modified_record(false);
    for (const auto &block_start_and_end : local_block_boundaries) {
        std::vector <size_t> _852_field_indices;
        if (MarcUtil::FindFieldsInLocalBlock("852", "??", block_start_and_end, *field_data, &_852_field_indices) == 0)
            continue;
        for (const size_t _852_index : _852_field_indices) {
            const Subfields subfields1((*field_data)[_852_index]);
            const std::string isil_subfield(subfields1.getFirstSubfieldValue('a'));

            if (isil_subfield != "DE-21" and isil_subfield != "DE-21-110")
                continue;

            const std::string institution(isil_subfield == "DE-21" ? "UB: " : "IFK: ");
            if (_852_index + 1 < block_start_and_end.second) {
                const Subfields subfields2((*field_data)[_852_index + 1]);
                const std::string callnumber_subfield(subfields2.getFirstSubfieldValue('c'));
                if (not callnumber_subfield.empty()) {
                    const std::string institution_and_call_number(institution + callnumber_subfield);
                    ++add_sig_count;
                    modified_record = true;
                    MarcUtil::InsertField(institution_and_call_number, "SIG", leader, dir_entries, field_data);
                }
            }
            break;
        }
    }

    if (modified_record)
        ++modified_record_count;

    MarcUtil::ComposeAndWriteRecord(output_ptr, *dir_entries, *field_data, leader);
    return true;
}

void PopulateTheInTuebingenAvailableField(const bool verbose, FILE * const input, FILE * const output) {
    output_ptr = output;

    std::string err_msg;
    if (not MarcUtil::ProcessRecords(input, ProcessRecord, &err_msg))
        Error("error while processing records: " + err_msg);

    if (verbose) {
        std::cout << "Modified " << modified_record_count << " records.\n";
        std::cout << "Added " << add_sig_count << " signature fields.\n";
    }
}

int main(int argc, char **argv) {
    progname = argv[0];

    if (argc != 3 and argc != 4)
        Usage();

    bool verbose;
    if (argc == 3)
        verbose = false;
    else { // argc == 4
        if (std::strcmp(argv[1], "--verbose") != 0)
            Usage();
        verbose = true;
    }

    const std::string marc_input_filename(argv[argc == 3 ? 1 : 2]);
    FILE * const marc_input(std::fopen(marc_input_filename.c_str(), "rbm"));
    if (marc_input == nullptr)
        Error("can't open \"" + marc_input_filename + "\" for reading!");

    const std::string marc_output_filename(argv[argc == 3 ? 2 : 3]);
    FILE * const marc_output(std::fopen(marc_output_filename.c_str(), "wb"));
    if (marc_output == nullptr)
        Error("can't open \"" + marc_output_filename + "\" for writing!");

    PopulateTheInTuebingenAvailableField(verbose, marc_input, marc_output);

    std::fclose(marc_input);
    std::fclose(marc_output);
}
<commit_msg>Changed signatures-string to multi value field<commit_after>/** \file    populate_in_tuebingen_available.cc
 *  \author  Dr. Johannes Ruscheinski
 *
 *  A tool that adds a new "SIG" field to a MARC record if there are UB or IFK call numbers in a record.
 */

/*
    Copyright (C) 2015, Library of the University of Tübingen

    This program 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.

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

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <iostream>
#include <cstdlib>
#include "DirectoryEntry.h"
#include "Leader.h"
#include "MarcUtil.h"
#include "StringUtil.h"
#include "Subfields.h"
#include "util.h"

void Usage() {
    std::cerr << "Usage: " << progname << " [--verbose] marc_input marc_output\n";
    std::exit(EXIT_FAILURE);
}

static FILE *output_ptr;
static unsigned modified_record_count;
static unsigned add_sig_count;

bool ProcessRecord(std::shared_ptr <Leader> &leader, std::vector <DirectoryEntry> * const dir_entries,
                   std::vector <std::string> * const field_data, std::string * const /*err_msg*/) {
    std::vector <std::pair<size_t, size_t>> local_block_boundaries;
    MarcUtil::FindAllLocalDataBlocks(*dir_entries, *field_data, &local_block_boundaries);

    bool modified_record(false);
    for (const auto &block_start_and_end : local_block_boundaries) {
        std::vector <size_t> _852_field_indices;
        if (MarcUtil::FindFieldsInLocalBlock("852", "??", block_start_and_end, *field_data, &_852_field_indices) == 0)
            continue;
        for (const size_t _852_index : _852_field_indices) {
            const Subfields subfields1((*field_data)[_852_index]);
            const std::string isil_subfield(subfields1.getFirstSubfieldValue('a'));

            if (isil_subfield != "DE-21" and isil_subfield != "DE-21-110")
                continue;

            const std::string institution(isil_subfield == "DE-21" ? "UB: " : "IFK: ");
            if (_852_index + 1 < block_start_and_end.second) {
                const Subfields subfields2((*field_data)[_852_index + 1]);
                const std::string call_number_subfield(subfields2.getFirstSubfieldValue('c'));
                if (not call_number_subfield.empty()) {
                    const std::string institution_and_call_number(institution + call_number_subfield);
                    ++add_sig_count;
                    modified_record = true;
                    MarcUtil::InsertField(institution_and_call_number, "SIG", leader, dir_entries, field_data);
                }
            }
            break;
        }
    }

    if (modified_record)
        ++modified_record_count;

    MarcUtil::ComposeAndWriteRecord(output_ptr, *dir_entries, *field_data, leader);
    return true;
}

void PopulateTheInTuebingenAvailableField(const bool verbose, FILE * const input, FILE * const output) {
    output_ptr = output;

    std::string err_msg;
    if (not MarcUtil::ProcessRecords(input, ProcessRecord, &err_msg))
        Error("error while processing records: " + err_msg);

    if (verbose) {
        std::cout << "Modified " << modified_record_count << " records.\n";
        std::cout << "Added " << add_sig_count << " signature fields.\n";
    }
}

int main(int argc, char **argv) {
    progname = argv[0];

    if (argc != 3 and argc != 4)
        Usage();

    bool verbose;
    if (argc == 3)
        verbose = false;
    else { // argc == 4
        if (std::strcmp(argv[1], "--verbose") != 0)
            Usage();
        verbose = true;
    }

    const std::string marc_input_filename(argv[argc == 3 ? 1 : 2]);
    FILE * const marc_input(std::fopen(marc_input_filename.c_str(), "rbm"));
    if (marc_input == nullptr)
        Error("can't open \"" + marc_input_filename + "\" for reading!");

    const std::string marc_output_filename(argv[argc == 3 ? 2 : 3]);
    FILE * const marc_output(std::fopen(marc_output_filename.c_str(), "wb"));
    if (marc_output == nullptr)
        Error("can't open \"" + marc_output_filename + "\" for writing!");

    PopulateTheInTuebingenAvailableField(verbose, marc_input, marc_output);

    std::fclose(marc_input);
    std::fclose(marc_output);
}
<|endoftext|>


<commit_before>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include <atomic>

#include <gtest/gtest.h>

#include "joynr/Directory.h"
#include "joynr/PrivateCopyAssign.h"
#include "joynr/SingleThreadedIOService.h"

using namespace joynr;

class TrackableObject
{
public:
    TrackableObject()
    {
        ++instances;
        JOYNR_LOG_TRACE(logger(),
                        "Creating TrackableObject at address {}. Now we have {} instances.",
                        static_cast<const void*>(this),
                        instances);
    }

    ~TrackableObject()
    {
        --instances;
        JOYNR_LOG_TRACE(logger(),
                        "Deleting TrackableObject at address {}. Now we have {} instances.",
                        static_cast<const void*>(this),
                        instances);
    }

    static int getInstances()
    {
        return instances;
    }

private:
    static std::atomic_int instances;
    ADD_LOGGER(TrackableObject)
};

std::atomic_int TrackableObject::instances;

class DirectoryTest : public ::testing::Test
{
public:
    DirectoryTest()
        : singleThreadedIOService(std::make_shared<SingleThreadedIOService>()),
          directory("Directory", singleThreadedIOService->getIOService()),
          testValue(nullptr),
          secondTestValue(nullptr),
          firstKey(""),
          secondKey("")
    {
        singleThreadedIOService->start();
    }

    void SetUp(){
        testValue = std::make_shared<std::string>("testValue");
        secondTestValue = std::make_shared<std::string>("secondTestValue");
        firstKey = std::string("firstKey");
        secondKey = std::string("secondKey");
    }

protected:
    std::shared_ptr<SingleThreadedIOService> singleThreadedIOService;
    Directory<std::string, std::string> directory;
    std::shared_ptr<std::string> testValue;
    std::shared_ptr<std::string> secondTestValue;
    std::string firstKey;
    std::string secondKey;
private:
    DISALLOW_COPY_AND_ASSIGN(DirectoryTest);
};

TEST_F(DirectoryTest, addAndContains)
{
    directory.add(firstKey, testValue);
    ASSERT_TRUE(directory.contains(firstKey));
}

TEST_F(DirectoryTest, containsNot)
{
    directory.add(firstKey, testValue);
    ASSERT_TRUE(directory.contains(firstKey));
    ASSERT_FALSE(directory.contains(secondKey));
}

TEST_F(DirectoryTest, lookup)
{
    directory.add(firstKey, testValue);
    directory.add(secondKey,secondTestValue);
    std::shared_ptr<std::string> result1 = directory.lookup(firstKey);
    std::shared_ptr<std::string> result2 = directory.lookup(secondKey);
    ASSERT_EQ(result1, testValue);
    ASSERT_EQ(result2, secondTestValue);
}

TEST_F(DirectoryTest, remove)
{
    directory.add(firstKey, testValue);
    directory.add(secondKey, secondTestValue);
    ASSERT_TRUE(directory.contains(firstKey));
    ASSERT_TRUE(directory.contains(secondKey));
    directory.remove(firstKey);
    ASSERT_FALSE(directory.contains(firstKey));
    ASSERT_TRUE(directory.contains(secondKey));
}

TEST_F(DirectoryTest, scheduledRemove)
{
    directory.add(firstKey, std::make_shared<std::string>("scheduledRemove_testValue"), 100);
    ASSERT_TRUE(directory.contains(firstKey));
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    ASSERT_FALSE(directory.contains(firstKey));
}

TEST_F(DirectoryTest, ObjectsAreDeletedByDirectoryAfterTtl)
{
    Directory<std::string, TrackableObject> directory("Directory", singleThreadedIOService->getIOService());
    {
        auto tp = std::make_shared<TrackableObject>();
        ASSERT_EQ(TrackableObject::getInstances(), 1);
        directory.add("key", tp, 100);
    }
    ASSERT_EQ(TrackableObject::getInstances(), 1) << "Directory copied / deleted object";
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    ASSERT_EQ(TrackableObject::getInstances(), 0) << "Directory did not delete Object";
}

TEST_F(DirectoryTest, ObjectsAreDeletedIfDirectoryIsDeleted)
{
    {
        Directory<std::string, TrackableObject> directory("Directory", singleThreadedIOService->getIOService());
        auto tp = std::make_shared<TrackableObject>();
        ASSERT_EQ(TrackableObject::getInstances(), 1);
        directory.add("key", tp, 100);
    }
    ASSERT_EQ(TrackableObject::getInstances(), 0) << "Directory did not delete Object";
}

TEST_F(DirectoryTest, useStdStringKeys)
{
    std::string key = "key";
    auto value = std::make_shared<std::string>("value");
    Directory<std::string, std::string> directory("Directory", singleThreadedIOService->getIOService());
    ASSERT_FALSE(directory.contains(key)) << "Empty directory contains entry.";
    directory.add(key, value);
    ASSERT_TRUE(directory.contains(key));
    ASSERT_EQ(value, directory.lookup(key));
    directory.remove(key);
    ASSERT_FALSE(directory.contains(key));
}

TEST_F(DirectoryTest, lookupNonExistingKeys)
{
    ASSERT_TRUE(nullptr == directory.lookup("__THIS__KEY__DOES__NOT__EXIST__"));
}

TEST_F(DirectoryTest, useLastTTLForKey)
{
    auto value = std::make_shared<std::string>("value");
    std::string key("key");

    directory.add(key, value, 100000); // Won't be removed after 50 ms (see sleep_for below)
    directory.add(key, value, 10);     // Will be removed after 50 ms

    std::this_thread::sleep_for(std::chrono::milliseconds(50));

    ASSERT_FALSE(directory.contains(key));
}
<commit_msg>[C++] Stop SingleThreadedIOService in DirectoryTest<commit_after>/*
 * #%L
 * %%
 * Copyright (C) 2011 - 2017 BMW Car IT GmbH
 * %%
 * 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.
 * #L%
 */

#include <atomic>

#include <gtest/gtest.h>

#include "joynr/Directory.h"
#include "joynr/PrivateCopyAssign.h"
#include "joynr/SingleThreadedIOService.h"

using namespace joynr;

class TrackableObject
{
public:
    TrackableObject()
    {
        ++instances;
        JOYNR_LOG_TRACE(logger(),
                        "Creating TrackableObject at address {}. Now we have {} instances.",
                        static_cast<const void*>(this),
                        instances);
    }

    ~TrackableObject()
    {
        --instances;
        JOYNR_LOG_TRACE(logger(),
                        "Deleting TrackableObject at address {}. Now we have {} instances.",
                        static_cast<const void*>(this),
                        instances);
    }

    static int getInstances()
    {
        return instances;
    }

private:
    static std::atomic_int instances;
    ADD_LOGGER(TrackableObject)
};

std::atomic_int TrackableObject::instances;

class DirectoryTest : public ::testing::Test
{
public:
    DirectoryTest()
        : singleThreadedIOService(std::make_shared<SingleThreadedIOService>()),
          directory("Directory", singleThreadedIOService->getIOService()),
          testValue(nullptr),
          secondTestValue(nullptr),
          firstKey(""),
          secondKey("")
    {
        singleThreadedIOService->start();
    }

    ~DirectoryTest() {
        singleThreadedIOService->stop();
    }

    void SetUp(){
        testValue = std::make_shared<std::string>("testValue");
        secondTestValue = std::make_shared<std::string>("secondTestValue");
        firstKey = std::string("firstKey");
        secondKey = std::string("secondKey");
    }

protected:
    std::shared_ptr<SingleThreadedIOService> singleThreadedIOService;
    Directory<std::string, std::string> directory;
    std::shared_ptr<std::string> testValue;
    std::shared_ptr<std::string> secondTestValue;
    std::string firstKey;
    std::string secondKey;
private:
    DISALLOW_COPY_AND_ASSIGN(DirectoryTest);
};

TEST_F(DirectoryTest, addAndContains)
{
    directory.add(firstKey, testValue);
    ASSERT_TRUE(directory.contains(firstKey));
}

TEST_F(DirectoryTest, containsNot)
{
    directory.add(firstKey, testValue);
    ASSERT_TRUE(directory.contains(firstKey));
    ASSERT_FALSE(directory.contains(secondKey));
}

TEST_F(DirectoryTest, lookup)
{
    directory.add(firstKey, testValue);
    directory.add(secondKey,secondTestValue);
    std::shared_ptr<std::string> result1 = directory.lookup(firstKey);
    std::shared_ptr<std::string> result2 = directory.lookup(secondKey);
    ASSERT_EQ(result1, testValue);
    ASSERT_EQ(result2, secondTestValue);
}

TEST_F(DirectoryTest, remove)
{
    directory.add(firstKey, testValue);
    directory.add(secondKey, secondTestValue);
    ASSERT_TRUE(directory.contains(firstKey));
    ASSERT_TRUE(directory.contains(secondKey));
    directory.remove(firstKey);
    ASSERT_FALSE(directory.contains(firstKey));
    ASSERT_TRUE(directory.contains(secondKey));
}

TEST_F(DirectoryTest, scheduledRemove)
{
    directory.add(firstKey, std::make_shared<std::string>("scheduledRemove_testValue"), 100);
    ASSERT_TRUE(directory.contains(firstKey));
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    ASSERT_FALSE(directory.contains(firstKey));
}

TEST_F(DirectoryTest, ObjectsAreDeletedByDirectoryAfterTtl)
{
    Directory<std::string, TrackableObject> directory("Directory", singleThreadedIOService->getIOService());
    {
        auto tp = std::make_shared<TrackableObject>();
        ASSERT_EQ(TrackableObject::getInstances(), 1);
        directory.add("key", tp, 100);
    }
    ASSERT_EQ(TrackableObject::getInstances(), 1) << "Directory copied / deleted object";
    std::this_thread::sleep_for(std::chrono::milliseconds(200));
    ASSERT_EQ(TrackableObject::getInstances(), 0) << "Directory did not delete Object";
}

TEST_F(DirectoryTest, ObjectsAreDeletedIfDirectoryIsDeleted)
{
    {
        Directory<std::string, TrackableObject> directory("Directory", singleThreadedIOService->getIOService());
        auto tp = std::make_shared<TrackableObject>();
        ASSERT_EQ(TrackableObject::getInstances(), 1);
        directory.add("key", tp, 100);
    }
    ASSERT_EQ(TrackableObject::getInstances(), 0) << "Directory did not delete Object";
}

TEST_F(DirectoryTest, useStdStringKeys)
{
    std::string key = "key";
    auto value = std::make_shared<std::string>("value");
    Directory<std::string, std::string> directory("Directory", singleThreadedIOService->getIOService());
    ASSERT_FALSE(directory.contains(key)) << "Empty directory contains entry.";
    directory.add(key, value);
    ASSERT_TRUE(directory.contains(key));
    ASSERT_EQ(value, directory.lookup(key));
    directory.remove(key);
    ASSERT_FALSE(directory.contains(key));
}

TEST_F(DirectoryTest, lookupNonExistingKeys)
{
    ASSERT_TRUE(nullptr == directory.lookup("__THIS__KEY__DOES__NOT__EXIST__"));
}

TEST_F(DirectoryTest, useLastTTLForKey)
{
    auto value = std::make_shared<std::string>("value");
    std::string key("key");

    directory.add(key, value, 100000); // Won't be removed after 50 ms (see sleep_for below)
    directory.add(key, value, 10);     // Will be removed after 50 ms

    std::this_thread::sleep_for(std::chrono::milliseconds(50));

    ASSERT_FALSE(directory.contains(key));
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  Author: Anatoly Baskeheev, Itseez Ltd, (myname.mysurname@mycompany.com)
 */

#ifndef PCL_GPU_FEATURES_TEST_DATA_SORUCE_HPP_
#define PCL_GPU_FEATURES_TEST_DATA_SORUCE_HPP_

#include<string>

#include "pcl/point_types.h"
#include "pcl/point_cloud.h"
#include "pcl/io/pcd_io.h"
#include "pcl/common/common.h"
#include "pcl/features/normal_3d.h"
#include "pcl/visualization/cloud_viewer.h"
#include "pcl/gpu/containers/kernel_containers.hpp"
#include <pcl/search/search.h>

#include <Eigen/StdVector>
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(pcl::PointXYZ)
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(pcl::Normal)

#include <algorithm>

namespace pcl
{
    namespace gpu
    {
        struct DataSource
        {
            const static int k = 32;
            const static int max_elements = 500;

            PointCloud<PointXYZ>::Ptr cloud;
            PointCloud<PointXYZ>::Ptr surface;
            IndicesPtr indices;

            PointCloud<Normal>::Ptr normals;
            PointCloud<Normal>::Ptr normals_surface;
            float radius;

            std::vector< std::vector<int> > neighbors_all;
            std::vector<int> sizes;
            int max_nn_size;

            DataSource(const std::string& file = "d:/office_chair_model.pcd")
                : cloud(new PointCloud<PointXYZ>()), surface(new PointCloud<PointXYZ>()), indices( new std::vector<int>() ),
                normals(new PointCloud<Normal>()), normals_surface(new PointCloud<Normal>())
            {
                PCDReader pcd;
                pcd.read(file, *cloud);

                PointXYZ minp, maxp;
                pcl::getMinMax3D(*cloud, minp, maxp);
                float sz = (maxp.x - minp.x + maxp.y - minp.y + maxp.z - minp.z) / 3;
                radius = sz / 15;
            }

            void generateColor()
            {
                size_t cloud_size = cloud->points.size();
                for(size_t i = 0; i < cloud_size; ++i)
                {
                    PointXYZ& p = cloud->points[i];

                    int r = std::max(1, std::min(255, static_cast<int>((double(rand())/RAND_MAX)*255)));
                    int g = std::max(1, std::min(255, static_cast<int>((double(rand())/RAND_MAX)*255)));
                    int b = std::max(1, std::min(255, static_cast<int>((double(rand())/RAND_MAX)*255)));

                    *reinterpret_cast<int*>(&p.data[3]) = (b << 16) + (g << 8) + r;
                }
            }

            void estimateNormals()
            {
                pcl::NormalEstimation<PointXYZ, Normal> ne;
                ne.setInputCloud (cloud);
                ne.setSearchMethod (pcl::search::KdTree<PointXYZ>::Ptr (new pcl::search::KdTree<PointXYZ>));
                ne.setKSearch (k);
                //ne.setRadiusSearch (radius);

                ne.compute (*normals);
            }

            void runCloudViewer() const
            {
                pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");
                viewer.showCloud (cloud);
                while (!viewer.wasStopped ()) {}
            }

            void findKNNeghbors()
            {
                KdTreeFLANN<PointXYZ>::Ptr kdtree(new KdTreeFLANN<PointXYZ>);
                kdtree->setInputCloud(cloud);

                size_t cloud_size = cloud->points.size();

                std::vector<float> dists;
                neighbors_all.resize(cloud_size);
                for(size_t i = 0; i < cloud_size; ++i)
                {
                    kdtree->nearestKSearch(cloud->points[i], k, neighbors_all[i], dists);
                    sizes.push_back((int)neighbors_all[i].size());
                }
                max_nn_size = *max_element(sizes.begin(), sizes.end());
            }

            void findRadiusNeghbors(float radius = -1)
            {
                radius = radius == -1 ? this->radius : radius;

                KdTreeFLANN<PointXYZ>::Ptr kdtree(new KdTreeFLANN<PointXYZ>);
                kdtree->setInputCloud(cloud);

                size_t cloud_size = cloud->points.size();

                std::vector<float> dists;
                neighbors_all.resize(cloud_size);
                for(size_t i = 0; i < cloud_size; ++i)
                {
                    kdtree->radiusSearch(cloud->points[i], radius, neighbors_all[i], dists);
                    sizes.push_back((int)neighbors_all[i].size());
                }
                max_nn_size = *max_element(sizes.begin(), sizes.end());
            }

            void getNeghborsArray(std::vector<int>& data)
            {
                data.resize(max_nn_size * neighbors_all.size());
                pcl::gpu::PtrStep<int> ps(&data[0], max_nn_size * sizeof(int));
                for(size_t i = 0; i < neighbors_all.size(); ++i)
                    copy(neighbors_all[i].begin(), neighbors_all[i].end(), ps.ptr(i));
            }

            void generateSurface()
            {
                surface->points.clear();
                for(size_t i = 0; i < cloud->points.size(); i+= 10)
                    surface->points.push_back(cloud->points[i]);
                surface->width = surface->points.size();
                surface->height = 1;

                if (!normals->points.empty())
                {
                    normals_surface->points.clear();
                    for(size_t i = 0; i < normals->points.size(); i+= 10)
                        normals_surface->points.push_back(normals->points[i]);

                    normals_surface->width = surface->points.size();
                    normals_surface->height = 1;
                }
            }

            void generateIndices()
            {
                indices->clear();
                for(size_t i = 0; i < cloud->points.size(); i +=100)
                    indices->push_back(i);
            }

            struct Normal2PointXYZ
            {
                PointXYZ operator()(const Normal& n) const
                {
                    PointXYZ xyz;
                    xyz.x = n.normal[0];
                    xyz.y = n.normal[1];
                    xyz.z = n.normal[2];
                    return xyz;
                }
            };
        };
    }
}

#endif /* PCL_GPU_FEATURES_TEST_DATA_SORUCE_HPP_ */
<commit_msg>wrapped EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION with #if defined (_WIN32) || defined(_WIN64)<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2011, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 *  Author: Anatoly Baskeheev, Itseez Ltd, (myname.mysurname@mycompany.com)
 */

#ifndef PCL_GPU_FEATURES_TEST_DATA_SORUCE_HPP_
#define PCL_GPU_FEATURES_TEST_DATA_SORUCE_HPP_

#include<string>

#include "pcl/point_types.h"
#include "pcl/point_cloud.h"
#include "pcl/io/pcd_io.h"
#include "pcl/common/common.h"
#include "pcl/features/normal_3d.h"
#include "pcl/visualization/cloud_viewer.h"
#include "pcl/gpu/containers/kernel_containers.hpp"
#include <pcl/search/search.h>

#include <Eigen/StdVector>

#if defined (_WIN32) || defined(_WIN64)
    EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(pcl::PointXYZ)
    EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(pcl::Normal)
#endif

#include <algorithm>

namespace pcl
{
    namespace gpu
    {
        struct DataSource
        {
            const static int k = 32;
            const static int max_elements = 500;

            PointCloud<PointXYZ>::Ptr cloud;
            PointCloud<PointXYZ>::Ptr surface;
            IndicesPtr indices;

            PointCloud<Normal>::Ptr normals;
            PointCloud<Normal>::Ptr normals_surface;
            float radius;

            std::vector< std::vector<int> > neighbors_all;
            std::vector<int> sizes;
            int max_nn_size;

            DataSource(const std::string& file = "d:/office_chair_model.pcd")
                : cloud(new PointCloud<PointXYZ>()), surface(new PointCloud<PointXYZ>()), indices( new std::vector<int>() ),
                normals(new PointCloud<Normal>()), normals_surface(new PointCloud<Normal>())
            {
                PCDReader pcd;
                pcd.read(file, *cloud);

                PointXYZ minp, maxp;
                pcl::getMinMax3D(*cloud, minp, maxp);
                float sz = (maxp.x - minp.x + maxp.y - minp.y + maxp.z - minp.z) / 3;
                radius = sz / 15;
            }

            void generateColor()
            {
                size_t cloud_size = cloud->points.size();
                for(size_t i = 0; i < cloud_size; ++i)
                {
                    PointXYZ& p = cloud->points[i];

                    int r = std::max(1, std::min(255, static_cast<int>((double(rand())/RAND_MAX)*255)));
                    int g = std::max(1, std::min(255, static_cast<int>((double(rand())/RAND_MAX)*255)));
                    int b = std::max(1, std::min(255, static_cast<int>((double(rand())/RAND_MAX)*255)));

                    *reinterpret_cast<int*>(&p.data[3]) = (b << 16) + (g << 8) + r;
                }
            }

            void estimateNormals()
            {
                pcl::NormalEstimation<PointXYZ, Normal> ne;
                ne.setInputCloud (cloud);
                ne.setSearchMethod (pcl::search::KdTree<PointXYZ>::Ptr (new pcl::search::KdTree<PointXYZ>));
                ne.setKSearch (k);
                //ne.setRadiusSearch (radius);

                ne.compute (*normals);
            }

            void runCloudViewer() const
            {
                pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");
                viewer.showCloud (cloud);
                while (!viewer.wasStopped ()) {}
            }

            void findKNNeghbors()
            {
                KdTreeFLANN<PointXYZ>::Ptr kdtree(new KdTreeFLANN<PointXYZ>);
                kdtree->setInputCloud(cloud);

                size_t cloud_size = cloud->points.size();

                std::vector<float> dists;
                neighbors_all.resize(cloud_size);
                for(size_t i = 0; i < cloud_size; ++i)
                {
                    kdtree->nearestKSearch(cloud->points[i], k, neighbors_all[i], dists);
                    sizes.push_back((int)neighbors_all[i].size());
                }
                max_nn_size = *max_element(sizes.begin(), sizes.end());
            }

            void findRadiusNeghbors(float radius = -1)
            {
                radius = radius == -1 ? this->radius : radius;

                KdTreeFLANN<PointXYZ>::Ptr kdtree(new KdTreeFLANN<PointXYZ>);
                kdtree->setInputCloud(cloud);

                size_t cloud_size = cloud->points.size();

                std::vector<float> dists;
                neighbors_all.resize(cloud_size);
                for(size_t i = 0; i < cloud_size; ++i)
                {
                    kdtree->radiusSearch(cloud->points[i], radius, neighbors_all[i], dists);
                    sizes.push_back((int)neighbors_all[i].size());
                }
                max_nn_size = *max_element(sizes.begin(), sizes.end());
            }

            void getNeghborsArray(std::vector<int>& data)
            {
                data.resize(max_nn_size * neighbors_all.size());
                pcl::gpu::PtrStep<int> ps(&data[0], max_nn_size * sizeof(int));
                for(size_t i = 0; i < neighbors_all.size(); ++i)
                    copy(neighbors_all[i].begin(), neighbors_all[i].end(), ps.ptr(i));
            }

            void generateSurface()
            {
                surface->points.clear();
                for(size_t i = 0; i < cloud->points.size(); i+= 10)
                    surface->points.push_back(cloud->points[i]);
                surface->width = surface->points.size();
                surface->height = 1;

                if (!normals->points.empty())
                {
                    normals_surface->points.clear();
                    for(size_t i = 0; i < normals->points.size(); i+= 10)
                        normals_surface->points.push_back(normals->points[i]);

                    normals_surface->width = surface->points.size();
                    normals_surface->height = 1;
                }
            }

            void generateIndices()
            {
                indices->clear();
                for(size_t i = 0; i < cloud->points.size(); i +=100)
                    indices->push_back(i);
            }

            struct Normal2PointXYZ
            {
                PointXYZ operator()(const Normal& n) const
                {
                    PointXYZ xyz;
                    xyz.x = n.normal[0];
                    xyz.y = n.normal[1];
                    xyz.z = n.normal[2];
                    return xyz;
                }
            };
        };
    }
}

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


<commit_before>/*
 * Copyright 2008 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay and David Thompson from Sandia National Laboratories
// for implementing this test.

#include "vtkDoubleArray.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkDescriptiveStatistics.h"

//=============================================================================
int TestDescriptiveStatistics( int, char *[] )
{
  int testStatus = 0;

  double mingledData[] =
    {
    46,
    45,
    47,
    49,
    46,
    47,
    46,
    46,
    47,
    46,
    47,
    49,
    49,
    49,
    47,
    45,
    50,
    50,
    46,
    46,
    51,
    50,
    48,
    48,
    52,
    54,
    48,
    47,
    52,
    52,
    49,
    49,
    53,
    54,
    50,
    50,
    53,
    54,
    50,
    52,
    53,
    53,
    50,
    51,
    54,
    54,
    49,
    49,
    52,
    52,
    50,
    51,
    52,
    52,
    49,
    47,
    48,
    48,
    48,
    50,
    46,
    48,
    47,
    47,
    };
  int nVals = 32;

  vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
  dataset1Arr->SetNumberOfComponents( 1 );
  dataset1Arr->SetName( "Metric 0" );

  vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
  dataset2Arr->SetNumberOfComponents( 1 );
  dataset2Arr->SetName( "Metric 1" );

  vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
  dataset3Arr->SetNumberOfComponents( 1 );
  dataset3Arr->SetName( "Metric 2" );

  for ( int i = 0; i < nVals; ++ i )
    {
    int ti = i << 1;
    dataset1Arr->InsertNextValue( mingledData[ti] );
    dataset2Arr->InsertNextValue( mingledData[ti + 1] );
    dataset3Arr->InsertNextValue( -1. );
    }

  vtkTable* datasetTable = vtkTable::New();
  datasetTable->AddColumn( dataset1Arr );
  dataset1Arr->Delete();
  datasetTable->AddColumn( dataset2Arr );
  dataset2Arr->Delete();
  datasetTable->AddColumn( dataset3Arr );
  dataset3Arr->Delete();

  int nMetrics = 3;
  vtkStdString columns[] = { "Metric 1", "Metric 2", "Metric 0" };
  double means[] = { 49.5, -1., 49.2188 };
  double stdevs[] = { sqrt( 7.54839 ), 0., sqrt( 5.98286 ) };

  vtkDescriptiveStatistics* haruspex = vtkDescriptiveStatistics::New();
  haruspex->SetInput( 0, datasetTable );
  vtkTable* outputData = haruspex->GetOutput( 0 );
  vtkTable* outputMeta = haruspex->GetOutput( 1 );

  datasetTable->Delete();

// -- Select Columns of Interest --
  haruspex->AddColumn( "Metric 3" ); // Include invalid Metric 3
  haruspex->AddColumn( "Metric 4" ); // Include invalid Metric 4
  for ( int i = 0; i< nMetrics; ++ i )
    {  // Try to add all valid indices once more
    haruspex->AddColumn( columns[i] );
    }
  haruspex->RemoveColumn( "Metric 3" ); // Remove invalid Metric 3 (but keep 4)

// -- Test Learn and Assess Modes --
  haruspex->SetLearn( true );
  haruspex->SetDerive( true );
  haruspex->SetAssess( true );
  haruspex->SignedDeviationsOff();
  haruspex->Update();
  vtkIdType n = haruspex->GetSampleSize();

  cout << "## Calculated the following statistics ( "
       << n
       << " entries per column ):\n";
  for ( vtkIdType r = 0; r < outputMeta->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputMeta->GetNumberOfColumns(); ++ i )
      {
      cout << outputMeta->GetColumnName( i )
           << "="
           << outputMeta->GetValue( r, i ).ToString()
           << "  ";
      }

    if ( fabs ( outputMeta->GetValueByName( r, "Mean" ).ToDouble() - means[r] ) > 1.e6 )
      {
      cout << "** Incorrect mean ** ";
      testStatus = 1;
      }

    if ( fabs ( outputMeta->GetValueByName( r, "Standard Deviation" ).ToDouble() - stdevs[r] ) > 1.e6 )
      {
      cout << "** Incorrect standard deviation **";
      testStatus = 1;
      }
    cout << "\n";
    }

  cout << "## Searching for outliers:\n";

  int m0outliers = 0;
  int m1outliers = 0;
  cout << "Outliers:\n";
  vtkDoubleArray* m0reld = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "d(Metric 0)" ) );
  vtkDoubleArray* m1reld = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "d(Metric 1)" ) );
  vtkDoubleArray* m0vals = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "Metric 0" ) );
  vtkDoubleArray* m1vals = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "Metric 1" ) );

  if ( ! m0reld || ! m1reld || ! m0vals || ! m1vals )
    {
    cout << "Error: "
         << "Empty output column(s).\n";
    testStatus = 1;

    return testStatus;
    }

  double dev;
  double maxdev = 1.5;
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    dev = m0reld->GetValue( r );
    if ( dev > maxdev )
      {
      ++ m0outliers;
      cout << "   "
           << " row "
           << r
           << ", "
           << m0reld->GetName()
           << " = "
           << dev
           << " > "
           << maxdev
           << " (value: "
           << m0vals->GetValue( r )
           << ")\n";
      }
    }
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    dev = m1reld->GetValue( r );
    if ( dev > maxdev )
      {
      ++ m1outliers;
      cout << "   "
           << " row "
           << r
           << ", "
           << m1reld->GetName()
           << " = "
           << dev
           << " > "
           << maxdev
           << " (value: "
           << m1vals->GetValue( r )
           << ")\n";
      }
    }
  cout
    << "Found " << m0outliers << " outliers for Metric 0"
    << " and " << m1outliers << " outliers for Metric 1.\n";
  if ( m0outliers != 4 || m1outliers != 6 )
    {
    cout
      << "Error: "
      << "Expected 4 outliers for Metric 0"
      << " and 6 outliers for Metric 1.\n";
    testStatus = 1;
    }

// -- Used modified output 1 as input 1 to test 0-deviation --
  cout << "Re-running with mean 50 and deviation 0 for metric 1:\n";

  vtkTable* paramsTable = vtkTable::New();
  paramsTable->ShallowCopy( outputMeta );
  paramsTable->SetValueByName( 1, "Standard Deviation", 0. );
  paramsTable->SetValueByName( 1, "Mean", 50. );

  haruspex->SetInput( 1, paramsTable );
  haruspex->SetLearn( false );
  haruspex->SetDerive( false ); // Do not recalculate nor rederive a model
  haruspex->SetAssess( true );
  haruspex->Update();

  m1vals = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "Metric 1" ) );
  m1reld = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "d(Metric 1)" ) );

  if ( ! m1reld || ! m1vals )
    {
    cout << "Error: "
         << "Empty output column(s).\n";
    testStatus = 1;

    return testStatus;
    }

  m1outliers = 0;

  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    dev = m1reld->GetValue( r );
    if ( dev )
      {
      ++ m1outliers;
      cout << "   "
           << " row "
           << r
           << ", "
           << m1reld->GetName()
           << " = "
           << dev
           << " (value: "
           << m1vals->GetValue( r )
           << ")\n";
      }
    }
  if ( m1outliers != 28 )
    {
    cout << "Error: Expected 28 outliers for Metric 1, found " << m1outliers << ".\n";
    testStatus = 1;
    }

  paramsTable->Delete();
  haruspex->Delete();

  return testStatus;
}
<commit_msg>STYLE: report errors using GenericWarnings rather than couts.<commit_after>/*
 * Copyright 2008 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */
// .SECTION Thanks
// Thanks to Philippe Pebay and David Thompson from Sandia National Laboratories
// for implementing this test.

#include "vtkDoubleArray.h"
#include "vtkStringArray.h"
#include "vtkTable.h"
#include "vtkDescriptiveStatistics.h"

//=============================================================================
int TestDescriptiveStatistics( int, char *[] )
{
  int testStatus = 0;

  double mingledData[] =
    {
    46,
    45,
    47,
    49,
    46,
    47,
    46,
    46,
    47,
    46,
    47,
    49,
    49,
    49,
    47,
    45,
    50,
    50,
    46,
    46,
    51,
    50,
    48,
    48,
    52,
    54,
    48,
    47,
    52,
    52,
    49,
    49,
    53,
    54,
    50,
    50,
    53,
    54,
    50,
    52,
    53,
    53,
    50,
    51,
    54,
    54,
    49,
    49,
    52,
    52,
    50,
    51,
    52,
    52,
    49,
    47,
    48,
    48,
    48,
    50,
    46,
    48,
    47,
    47,
    };
  int nVals = 32;

  vtkDoubleArray* dataset1Arr = vtkDoubleArray::New();
  dataset1Arr->SetNumberOfComponents( 1 );
  dataset1Arr->SetName( "Metric 0" );

  vtkDoubleArray* dataset2Arr = vtkDoubleArray::New();
  dataset2Arr->SetNumberOfComponents( 1 );
  dataset2Arr->SetName( "Metric 1" );

  vtkDoubleArray* dataset3Arr = vtkDoubleArray::New();
  dataset3Arr->SetNumberOfComponents( 1 );
  dataset3Arr->SetName( "Metric 2" );

  for ( int i = 0; i < nVals; ++ i )
    {
    int ti = i << 1;
    dataset1Arr->InsertNextValue( mingledData[ti] );
    dataset2Arr->InsertNextValue( mingledData[ti + 1] );
    dataset3Arr->InsertNextValue( -1. );
    }

  vtkTable* datasetTable = vtkTable::New();
  datasetTable->AddColumn( dataset1Arr );
  dataset1Arr->Delete();
  datasetTable->AddColumn( dataset2Arr );
  dataset2Arr->Delete();
  datasetTable->AddColumn( dataset3Arr );
  dataset3Arr->Delete();

  int nMetrics = 3;
  vtkStdString columns[] = { "Metric 1", "Metric 2", "Metric 0" };
  double means[] = { 49.5, -1., 49.2188 };
  double stdevs[] = { sqrt( 7.54839 ), 0., sqrt( 5.98286 ) };

  vtkDescriptiveStatistics* haruspex = vtkDescriptiveStatistics::New();
  haruspex->SetInput( 0, datasetTable );
  vtkTable* outputData = haruspex->GetOutput( 0 );
  vtkTable* outputMeta = haruspex->GetOutput( 1 );

  datasetTable->Delete();

// -- Select Columns of Interest --
  haruspex->AddColumn( "Metric 3" ); // Include invalid Metric 3
  haruspex->AddColumn( "Metric 4" ); // Include invalid Metric 4
  for ( int i = 0; i< nMetrics; ++ i )
    {  // Try to add all valid indices once more
    haruspex->AddColumn( columns[i] );
    }
  haruspex->RemoveColumn( "Metric 3" ); // Remove invalid Metric 3 (but keep 4)

// -- Test Learn and Assess Modes --
  haruspex->SetLearn( true );
  haruspex->SetDerive( true );
  haruspex->SetAssess( true );
  haruspex->SignedDeviationsOff();
  haruspex->Update();
  vtkIdType n = haruspex->GetSampleSize();

  cout << "## Calculated the following statistics ( "
       << n
       << " entries per column ):\n";
  for ( vtkIdType r = 0; r < outputMeta->GetNumberOfRows(); ++ r )
    {
    cout << "   ";
    for ( int i = 0; i < outputMeta->GetNumberOfColumns(); ++ i )
      {
      cout << outputMeta->GetColumnName( i )
           << "="
           << outputMeta->GetValue( r, i ).ToString()
           << "  ";
      }

    if ( fabs ( outputMeta->GetValueByName( r, "Mean" ).ToDouble() - means[r] ) > 1.e6 )
      {
      vtkGenericWarningMacro("Incorrect mean");
      testStatus = 1;
      }

    if ( fabs ( outputMeta->GetValueByName( r, "Standard Deviation" ).ToDouble() - stdevs[r] ) > 1.e6 )
      {
      vtkGenericWarningMacro("Incorrect standard deviation");
      testStatus = 1;
      }
    cout << "\n";
    }

  cout << "## Searching for outliers:\n";

  int m0outliers = 0;
  int m1outliers = 0;
  cout << "Outliers:\n";
  vtkDoubleArray* m0reld = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "d(Metric 0)" ) );
  vtkDoubleArray* m1reld = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "d(Metric 1)" ) );
  vtkDoubleArray* m0vals = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "Metric 0" ) );
  vtkDoubleArray* m1vals = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "Metric 1" ) );

  if ( ! m0reld || ! m1reld || ! m0vals || ! m1vals )
    {
    vtkGenericWarningMacro("Empty output column(s).\n");
    testStatus = 1;

    return testStatus;
    }

  double dev;
  double maxdev = 1.5;
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    dev = m0reld->GetValue( r );
    if ( dev > maxdev )
      {
      ++ m0outliers;
      cout << "   "
           << " row "
           << r
           << ", "
           << m0reld->GetName()
           << " = "
           << dev
           << " > "
           << maxdev
           << " (value: "
           << m0vals->GetValue( r )
           << ")\n";
      }
    }
  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    dev = m1reld->GetValue( r );
    if ( dev > maxdev )
      {
      ++ m1outliers;
      cout << "   "
           << " row "
           << r
           << ", "
           << m1reld->GetName()
           << " = "
           << dev
           << " > "
           << maxdev
           << " (value: "
           << m1vals->GetValue( r )
           << ")\n";
      }
    }
  cout
    << "Found " << m0outliers << " outliers for Metric 0"
    << " and " << m1outliers << " outliers for Metric 1.\n";
  if ( m0outliers != 4 || m1outliers != 6 )
    {
    vtkGenericWarningMacro("Expected 4 outliers for Metric 0 and 6 outliers for Metric 1.");
    testStatus = 1;
    }

// -- Used modified output 1 as input 1 to test 0-deviation --
  cout << "Re-running with mean 50 and deviation 0 for metric 1:\n";

  vtkTable* paramsTable = vtkTable::New();
  paramsTable->ShallowCopy( outputMeta );
  paramsTable->SetValueByName( 1, "Standard Deviation", 0. );
  paramsTable->SetValueByName( 1, "Mean", 50. );

  haruspex->SetInput( 1, paramsTable );
  haruspex->SetLearn( false );
  haruspex->SetDerive( false ); // Do not recalculate nor rederive a model
  haruspex->SetAssess( true );
  haruspex->Update();

  m1vals = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "Metric 1" ) );
  m1reld = vtkDoubleArray::SafeDownCast(
    outputData->GetColumnByName( "d(Metric 1)" ) );

  if ( ! m1reld || ! m1vals )
    {
    vtkGenericWarningMacro("Empty output column(s).\n");
    testStatus = 1;

    return testStatus;
    }

  m1outliers = 0;

  for ( vtkIdType r = 0; r < outputData->GetNumberOfRows(); ++ r )
    {
    dev = m1reld->GetValue( r );
    if ( dev )
      {
      ++ m1outliers;
      cout << "   "
           << " row "
           << r
           << ", "
           << m1reld->GetName()
           << " = "
           << dev
           << " (value: "
           << m1vals->GetValue( r )
           << ")\n";
      }
    }
  if ( m1outliers != 28 )
    {
    vtkGenericWarningMacro("Expected 28 outliers for Metric 1, found " << m1outliers << ".");
    testStatus = 1;
    }

  paramsTable->Delete();
  haruspex->Delete();

  return testStatus;
}
<|endoftext|>