<commit_before>#include <QDir>
#include <QDateTime>
#include <QUdpSocket>

#include <protobuf/messages_robocup_ssl_wrapper.pb.h>
#include <protobuf/LogFrame.pb.h>
#include <git_version.hpp>

#include <multicast.hpp>
#include <Network.hpp>
#include <Utils.hpp>

#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <termios.h>

using namespace std;
using namespace Packet;

int main(int argc, char* argv[]) {
    int framePeriod = 1000000 / 60;

    QString logFile;

    // Determine log file name
    if (argc == 2) {
        logFile = argv[1];
    }

    if (logFile.isNull()) {
        if (!QDir("logs").exists()) {
            printf("No logs directory and no log file specified\n");
            return 1;
        }

        logFile = QString("logs/") +
                  QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss.log");
    }

    // Create vision socket
    QUdpSocket visionSocket;
    if (!visionSocket.bind(SharedVisionPortDoubleNew,
                           QUdpSocket::ShareAddress)) {
        printf("Can't bind to shared vision port");
        return 1;
    }
    multicast_add(&visionSocket, SharedVisionAddress);

    // Create referee socket
    QUdpSocket refereeSocket;
    if (!refereeSocket.bind(LegacyRefereePort, QUdpSocket::ShareAddress)) {
        printf("Can't bind to referee port");
        return 1;
    }
    multicast_add(&refereeSocket, RefereeAddress);

    // Create log file
    int fd = creat(logFile.toLatin1(), 0666);
    if (fd < 0) {
        printf("Can't create %s: %m\n", (const char*)logFile.toLatin1());
        return 1;
    }

    printf("Writing to %s\n", (const char*)logFile.toLatin1());

    // Main loop
    LogFrame logFrame;
    bool first = true;
    while (true) {
        RJ::Time startTime = RJ::timestamp();

        logFrame.Clear();
        logFrame.set_command_time(startTime);
        logFrame.set_timestamp(startTime);

        // Check for user input (to exit)
        struct pollfd pfd;
        pfd.fd = 0;
        pfd.events = POLLIN;
        if (poll(&pfd, 1, 0) > 0) {
            // Enter pressed
            break;
        }

        // Read vision data
        while (visionSocket.hasPendingDatagrams()) {
            string buf;
            unsigned int n = visionSocket.pendingDatagramSize();
            buf.resize(n);
            visionSocket.readDatagram(&buf[0], n);

            SSL_WrapperPacket* packet = logFrame.add_raw_vision();
            if (!packet->ParseFromString(buf)) {
                printf("Bad vision packet of %d bytes\n", n);
                continue;
            }
        }

        // Read referee data
        while (refereeSocket.hasPendingDatagrams()) {
            unsigned int n = refereeSocket.pendingDatagramSize();
            string str(6, 0);
            refereeSocket.readDatagram(&str[0], str.size());

            // Check the size after receiving to discard bad packets
            if (n != str.size()) {
                printf("Bad referee packet of %d bytes\n", n);
                continue;
            }

            logFrame.add_raw_referee(str);
        }

        if (first) {
            first = false;

            LogConfig* logConfig = logFrame.mutable_log_config();
            logConfig->set_generator("simple_logger");
            logConfig->set_git_version_hash(git_version_hash);
            logConfig->set_git_version_dirty(git_version_dirty);
        }

        uint32_t size = logFrame.ByteSize();
        if (write(fd, &size, sizeof(size)) != sizeof(size)) {
            printf("Failed to write size: %m\n");
            break;
        } else if (!logFrame.SerializeToFileDescriptor(fd)) {
            printf("Failed to write frame: %m\n");
            break;
        }

        RJ::Time endTime = RJ::timestamp();
        int lastFrameTime = endTime - startTime;
        if (lastFrameTime < framePeriod) {
            usleep(framePeriod - lastFrameTime);
        } else {
            printf("Processor took too long: %d us\n", lastFrameTime);
        }
    }

    // Discard input on stdin
    tcflush(0, TCIFLUSH);

    printf("Done.\n");

    return 0;
}
<commit_msg>should be working, but need protobuf file from another branch<commit_after>#include <QDir>
#include <QDateTime>
#include <QUdpSocket>

#include <protobuf/messages_robocup_ssl_wrapper.pb.h>
#include <protobuf/LogFrame.pb.h>
#include <protobuf/referee.pb.h>
#include <git_version.hpp>

#include <multicast.hpp>
#include <Network.hpp>
#include <Utils.hpp>

#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#include <termios.h>

using namespace std;
using namespace Packet;

int main(int argc, char* argv[]) {
    int framePeriod = 1000000 / 60;

    QString logFile;

    // Determine log file name
    if (argc == 2) {
        logFile = argv[1];
    }

    if (logFile.isNull()) {
        if (!QDir("logs").exists()) {
            printf("No logs directory and no log file specified\n");
            return 1;
        }

        logFile = QString("logs/") +
                  QDateTime::currentDateTime().toString("yyyyMMdd-hhmmss.log");
    }

    // Create vision socket
    QUdpSocket visionSocket;
    if (!visionSocket.bind(SharedVisionPortDoubleNew,
                           QUdpSocket::ShareAddress)) {
        printf("Can't bind to shared vision port");
        return 1;
    }
    multicast_add(&visionSocket, SharedVisionAddress);

    // Create referee socket
    QUdpSocket refereeSocket;
    if (!refereeSocket.bind(ProtobufRefereePort, QUdpSocket::ShareAddress)) {
        throw runtime_error("Can't bind to shared referee port");
    }

    multicast_add(&refereeSocket, RefereeAddress);

    // Create log file
    int fd = creat(logFile.toLatin1(), 0666);
    if (fd < 0) {
        printf("Can't create %s: %m\n", (const char*)logFile.toLatin1());
        return 1;
    }

    printf("Writing to %s\n", (const char*)logFile.toLatin1());

    // Main loop
    LogFrame logFrame;
    bool first = true;
    while (true) {
        RJ::Time startTime = RJ::timestamp();

        logFrame.Clear();
        logFrame.set_command_time(startTime);
        logFrame.set_timestamp(startTime);

        // Check for user input (to exit)
        struct pollfd pfd;
        pfd.fd = 0;
        pfd.events = POLLIN;
        if (poll(&pfd, 1, 0) > 0) {
            // Enter pressed
            break;
        }

        // Read vision data
        while (visionSocket.hasPendingDatagrams()) {
            string buf;
            unsigned int n = visionSocket.pendingDatagramSize();
            buf.resize(n);
            visionSocket.readDatagram(&buf[0], n);

            SSL_WrapperPacket* packet = logFrame.add_raw_vision();
            if (!packet->ParseFromString(buf)) {
                printf("Bad vision packet of %d bytes\n", n);
                continue;
            }
        }

        // Read referee data
        while (refereeSocket.hasPendingDatagrams()) {
            string buf;
            unsigned int n = refereeSocket.pendingDatagramSize();
            buf.resize(n);
            refereeSocket.readDatagram(&buf[0], n);

            SSL_Referee* packet = logFrame.add_raw_refbox();
            if (!packet->ParseFromString(buf)) {
                printf("Bad referee packet of %d bytes\n", n);
                continue;
            }
        }

        if (first) {
            first = false;

            LogConfig* logConfig = logFrame.mutable_log_config();
            logConfig->set_generator("simple_logger");
            logConfig->set_git_version_hash(git_version_hash);
            logConfig->set_git_version_dirty(git_version_dirty);
        }

        uint32_t size = logFrame.ByteSize();
        if (write(fd, &size, sizeof(size)) != sizeof(size)) {
            printf("Failed to write size: %m\n");
            break;
        } else if (!logFrame.SerializeToFileDescriptor(fd)) {
            printf("Failed to write frame: %m\n");
            break;
        }

        RJ::Time endTime = RJ::timestamp();
        int lastFrameTime = endTime - startTime;
        if (lastFrameTime < framePeriod) {
            usleep(framePeriod - lastFrameTime);
        } else {
            printf("Processor took too long: %d us\n", lastFrameTime);
        }
    }

    // Discard input on stdin
    tcflush(0, TCIFLUSH);

    printf("Done.\n");

    return 0;
}
<|endoftext|>


<commit_before>#include <cmath>
#include <cstdlib>
#include <ctime>
#include "StateSpace.h"
#include "Action.h"
#include "PriorityQueue.h"
#include "State.h"

//function to calculate a temperature for the select action function as a function of time
double temperature();

//function to select next action
Action * selectAction(PriorityQueue<Action *,double>& a_queue);

//function to update a q value
void updateQ(StateSpace & space, Action & action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(std::time(NULL));

	//create pointers to the possible actions as well as a pointer to hold the chosen action
	Action* chosen_action;
	Action* actions[2];
	actions[0]=new Action(FORWARD);
	actions[1]=new Action(BACKWARD);

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<Action*,double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(actions[0],0);
	initiator_queue.enqueueWithPriority(actions[1],0);

	//create the state space
	StateSpace space(100,50,initiator_queue);

	//state objects
	State current_state(0,0,FORWARD);
	State old_state(0,0,FORWARD);

	while(true)
	{
		current_state.theta=getAngle();
		current_state.theta_dot=getVelocity();
		current_state.robot_state=chosen_action.action;

		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		old_state=current_state;

		chosen_action=selectAction(space[current_state]);

		chosen_action.execute();
	}

	delete actions[0];
	delete actions[1];

	return 1;
}

double temperature()
{
	return std::time(NULL);
}

//function is fed with a priority queue of action-values
//generates Boltzmann distribution of these action-values
//and selects an action based on probabilities
Action * selectAction(PriorityQueue<Action *,double>& a_queue)
{
	typedef PriorityQueue<Action *,double> PQ;
	typedef std::vector< std::pair<Action *, double> > Vec_Pair;
	typedef std::pair<Action *, double> Pair;

	double sum= 0;
	int i = 0;

	int size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(std::vector< std::pair<int, double> >::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()/ (RAND_MAX));

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return NULL; //note that this line should never be reached
}

void updateQ(StateSpace & space, Action * action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[current_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    // change priority of action to new Q value
    space[old_state].changePriority(action, newQ);
}
<commit_msg>Update Main.cpp<commit_after>#include <cmath>
#include <cstdlib>
#include <ctime>
#include "StateSpace.h"
#include "Action.h"
#include "PriorityQueue.h"
#include "State.h"

//function to calculate a temperature for the select action function as a function of time
double temperature();

//function to select next action
Action * selectAction(PriorityQueue<Action *,double>& a_queue);

//function to update a q value
void updateQ(StateSpace & space, Action & action, State & new_state, State & old_state, double alpha, double gamma);

int main()
{
	//learning factor
	const double alpha=0.5;
	//discount factor
	const double gamma=0.5;

	//seed rng
	std::srand(std::time(NULL));

	//create pointers to the possible actions as well as a pointer to hold the chosen action
	Action* chosen_action;
	Action* actions[2];
	actions[0]=new Action(FORWARD,/*function pointer here*/);
	actions[1]=new Action(BACKWARD,/*function pointer here*/);

	//create a priority queue to copy to all the state space priority queues
	PriorityQueue<Action*,double> initiator_queue(MAX);
	initiator_queue.enqueueWithPriority(actions[0],0);
	initiator_queue.enqueueWithPriority(actions[1],0);

	//create the state space
	StateSpace space(100,50,initiator_queue);

	//state objects
	State current_state(0,0,FORWARD);
	State old_state(0,0,FORWARD);

	while(true)
	{
		current_state.theta=getAngle();
		current_state.theta_dot=getVelocity();
		current_state.robot_state=chosen_action.action;

		updateQ(space, chosen_action, old_state, current_state, alpha, gamma);

		old_state=current_state;

		chosen_action=selectAction(space[current_state]);

		chosen_action.execute();
	}

	delete actions[0];
	delete actions[1];

	return 1;
}

double temperature()
{
	return std::time(NULL);
}

//function is fed with a priority queue of action-values
//generates Boltzmann distribution of these action-values
//and selects an action based on probabilities
Action * selectAction(PriorityQueue<Action *,double>& a_queue)
{
	typedef PriorityQueue<Action *,double> PQ;
	typedef std::vector< std::pair<Action *, double> > Vec_Pair;
	typedef std::pair<Action *, double> Pair;

	double sum= 0;
	int i = 0;

	int size = a_queue.getSize();
	Vec_Pair action_vec(size);

	//Calculate partition function by iterating over action-values
	for(PQ::const_iterator iter = a_queue.begin(),end=a_queue.end(); iter < end; ++iter)
	{
		sum += std::exp((iter->second)/temperature());
	}
	//Calculate boltzmann factors for action-values
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
	    it->first = a_queue[i].first;
	    it->second = std::exp(a_queue[i].second /temperature()) / sum;
	    ++i;
	}

	//calculate cumulative probability distribution
	for(std::vector< std::pair<int, double> >::iterator it1 = action_vec.begin()++,it2 = action_vec.begin(),end=action_vec.end(); it < end; ++it1,++it2)
	{
	    it1->second += it2->second;
	}

	//generate RN between 0 and 1
	double rand_num = static_cast<double>(rand()/ (RAND_MAX));

	//select action based on probability
	for(Vec_Pair::iterator it = action_vec.begin(),end=action_vec.end(); it < end; ++it)
	{
		//if RN falls within cumulative probability bin return the corresponding action
		if(rand_num < it->second)return it->first;
	}

	return NULL; //note that this line should never be reached
}

void updateQ(StateSpace & space, Action * action, State & new_state, State & old_state, double alpha, double gamma)
{
    //oldQ value reference
    double oldQ = space[old_state].search(action).second;

    //reward given to current state
    double R = new_state.getReward();

    //optimal Q value for new state i.e. first element
    double maxQ = space[current_state].peekFront().second;

    //new Q value determined by Q learning algorithm
    double newQ = oldQ + alpha * (R + (gamma * maxQ) - oldQ);

    // change priority of action to new Q value
    space[old_state].changePriority(action, newQ);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "useragent.h"

#include <Cutelyst/Engine>
#include <Cutelyst/Context>
#include <Cutelyst/Request>
#include <Cutelyst/Response>

#include <QHostAddress>
#include <QLoggingCategory>
#include <QNetworkAccessManager>

#include <QBuffer>
#include <QHttpMultiPart>

#include <QJsonDocument>

using namespace Cutelyst;

Q_LOGGING_CATEGORY(C_USERAGENT, "cutelyst.useragent", QtInfoMsg)

static thread_local QNetworkAccessManager m_instance;

QNetworkAccessManager *Cutelyst::UA::networkAccessManager()
{
    return &m_instance;
}

QNetworkReply *UA::head(const QNetworkRequest &request)
{
    return m_instance.head(request);
}

QNetworkReply *UA::get(const QNetworkRequest &request)
{
    return m_instance.get(request);
}

QNetworkReply *UA::post(const QNetworkRequest &request, QIODevice *data)
{
    return m_instance.post(request, data);
}

QNetworkReply *UA::post(const QNetworkRequest &request, const QByteArray &data)
{
    return m_instance.post(request, data);
}

QNetworkReply *UA::put(const QNetworkRequest &request, QIODevice *data)
{
    return m_instance.put(request, data);
}

QNetworkReply *UA::put(const QNetworkRequest &request, const QByteArray &data)
{
    return m_instance.put(request, data);
}

QNetworkReply *UA::deleteResource(const QNetworkRequest &request)
{
    return m_instance.deleteResource(request);
}

QNetworkReply *UA::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data)
{
    return m_instance.sendCustomRequest(request, verb, data);
}

QNetworkReply *UA::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
    return m_instance.sendCustomRequest(request, verb, data);
#else
    auto buffer = new QBuffer;
    buffer->setData(data);
    QNetworkReply *reply = m_instance.sendCustomRequest(request, verb, buffer);
    buffer->setParent(reply);
    return reply;
#endif
}

QNetworkReply *UA::post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
    return m_instance.post(request, multiPart);
}

QNetworkReply *UA::put(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
    return m_instance.post(request, multiPart);
}

QNetworkReply *UA::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
    return m_instance.sendCustomRequest(request, verb, multiPart);
#else
    return nullptr;
#endif
}

QNetworkReply *UA::postJson(const QNetworkRequest &request, const QJsonDocument &doc)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.post(jsonRequest, doc.toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::putJson(const QNetworkRequest &request, const QJsonDocument &doc)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.put(jsonRequest, doc.toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::sendCustomRequestJson(const QNetworkRequest &request, const QByteArray &verb, const QJsonDocument &doc)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return UA::sendCustomRequest(jsonRequest, verb, doc.toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::postJsonObject(const QNetworkRequest &request, const QJsonObject &obj)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.post(jsonRequest, QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::putJsonObject(const QNetworkRequest &request, const QJsonObject &obj)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.put(jsonRequest, QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::sendCustomRequestJsonObject(const QNetworkRequest &request, const QByteArray &verb, const QJsonObject &obj)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return UA::sendCustomRequest(jsonRequest, verb, QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::postJsonArray(const QNetworkRequest &request, const QJsonArray &array)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.post(jsonRequest, QJsonDocument(array).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::putJsonArray(const QNetworkRequest &request, const QJsonArray &array)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.put(jsonRequest, QJsonDocument(array).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::sendCustomRequestJsonArray(const QNetworkRequest &request, const QByteArray &verb, const QJsonArray &array)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return UA::sendCustomRequest(jsonRequest, verb, QJsonDocument(array).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::forwardRequest(Request *request, const QUrl &destination)
{
    QUrl dest(request->uri());
    dest.setHost(destination.host());
    dest.setPort(destination.port());
    dest.setScheme(destination.scheme());

    QNetworkRequest proxyReq(dest);

    const Headers reqHeaders = request->headers();
    const auto headersData = reqHeaders.data();
    auto it = headersData.constBegin();
    while (it != headersData.constEnd()) {
        proxyReq.setRawHeader(Cutelyst::Engine::camelCaseHeader(it.key()).toLatin1(), it.value().toLatin1());
        ++it;
    }

    return m_instance.sendCustomRequest(proxyReq, request->method().toLatin1(), request->body());
}

QNetworkReply *UA::forwardRequestResponse(Context *c, const QUrl &destination)
{
    QNetworkReply *reply = forwardRequest(c->request(), destination);
    QObject::connect(reply, &QNetworkReply::finished, reply, [=] {
        Headers &responseHeaders = c->response()->headers();
        const QList<QNetworkReply::RawHeaderPair> &headers = reply->rawHeaderPairs();
        for (const QNetworkReply::RawHeaderPair &pair : headers) {
            responseHeaders.setHeader(QString::fromLatin1(pair.first), QString::fromLatin1(pair.second));
        }
        c->response()->setStatus(quint16(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt()));
        c->response()->setBody(reply);
    });
    return reply;
}

void UA::forwardAsync(Context *c, const QUrl &destination)
{
    QNetworkReply *reply = forwardRequest(c->request(), destination);
    QObject::connect(reply, &QNetworkReply::finished, reply, [=] {
        Headers &responseHeaders = c->response()->headers();
        const QList<QNetworkReply::RawHeaderPair> &headers = reply->rawHeaderPairs();
        for (const QNetworkReply::RawHeaderPair &pair : headers) {
            responseHeaders.setHeader(QString::fromLatin1(pair.first), QString::fromLatin1(pair.second));
        }
        c->response()->setStatus(quint16(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt()));
        c->response()->setBody(reply);
        c->attachAsync();
    });
    c->detachAsync();
}
<commit_msg>UA: Use Context as lambda owner<commit_after>/*
 * Copyright (C) 2019 Daniel Nicoletti <dantti12@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
#include "useragent.h"

#include <Cutelyst/Engine>
#include <Cutelyst/Context>
#include <Cutelyst/Request>
#include <Cutelyst/Response>

#include <QHostAddress>
#include <QLoggingCategory>
#include <QNetworkAccessManager>

#include <QBuffer>
#include <QHttpMultiPart>

#include <QJsonDocument>

using namespace Cutelyst;

Q_LOGGING_CATEGORY(C_USERAGENT, "cutelyst.useragent", QtInfoMsg)

static thread_local QNetworkAccessManager m_instance;

QNetworkAccessManager *Cutelyst::UA::networkAccessManager()
{
    return &m_instance;
}

QNetworkReply *UA::head(const QNetworkRequest &request)
{
    return m_instance.head(request);
}

QNetworkReply *UA::get(const QNetworkRequest &request)
{
    return m_instance.get(request);
}

QNetworkReply *UA::post(const QNetworkRequest &request, QIODevice *data)
{
    return m_instance.post(request, data);
}

QNetworkReply *UA::post(const QNetworkRequest &request, const QByteArray &data)
{
    return m_instance.post(request, data);
}

QNetworkReply *UA::put(const QNetworkRequest &request, QIODevice *data)
{
    return m_instance.put(request, data);
}

QNetworkReply *UA::put(const QNetworkRequest &request, const QByteArray &data)
{
    return m_instance.put(request, data);
}

QNetworkReply *UA::deleteResource(const QNetworkRequest &request)
{
    return m_instance.deleteResource(request);
}

QNetworkReply *UA::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QIODevice *data)
{
    return m_instance.sendCustomRequest(request, verb, data);
}

QNetworkReply *UA::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, const QByteArray &data)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
    return m_instance.sendCustomRequest(request, verb, data);
#else
    auto buffer = new QBuffer;
    buffer->setData(data);
    QNetworkReply *reply = m_instance.sendCustomRequest(request, verb, buffer);
    buffer->setParent(reply);
    return reply;
#endif
}

QNetworkReply *UA::post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
    return m_instance.post(request, multiPart);
}

QNetworkReply *UA::put(const QNetworkRequest &request, QHttpMultiPart *multiPart)
{
    return m_instance.post(request, multiPart);
}

QNetworkReply *UA::sendCustomRequest(const QNetworkRequest &request, const QByteArray &verb, QHttpMultiPart *multiPart)
{
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
    return m_instance.sendCustomRequest(request, verb, multiPart);
#else
    return nullptr;
#endif
}

QNetworkReply *UA::postJson(const QNetworkRequest &request, const QJsonDocument &doc)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.post(jsonRequest, doc.toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::putJson(const QNetworkRequest &request, const QJsonDocument &doc)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.put(jsonRequest, doc.toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::sendCustomRequestJson(const QNetworkRequest &request, const QByteArray &verb, const QJsonDocument &doc)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return UA::sendCustomRequest(jsonRequest, verb, doc.toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::postJsonObject(const QNetworkRequest &request, const QJsonObject &obj)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.post(jsonRequest, QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::putJsonObject(const QNetworkRequest &request, const QJsonObject &obj)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.put(jsonRequest, QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::sendCustomRequestJsonObject(const QNetworkRequest &request, const QByteArray &verb, const QJsonObject &obj)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return UA::sendCustomRequest(jsonRequest, verb, QJsonDocument(obj).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::postJsonArray(const QNetworkRequest &request, const QJsonArray &array)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.post(jsonRequest, QJsonDocument(array).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::putJsonArray(const QNetworkRequest &request, const QJsonArray &array)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return m_instance.put(jsonRequest, QJsonDocument(array).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::sendCustomRequestJsonArray(const QNetworkRequest &request, const QByteArray &verb, const QJsonArray &array)
{
    QNetworkRequest jsonRequest(request);
    jsonRequest.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/json"));
    return UA::sendCustomRequest(jsonRequest, verb, QJsonDocument(array).toJson(QJsonDocument::Compact));
}

QNetworkReply *UA::forwardRequest(Request *request, const QUrl &destination)
{
    QUrl dest(request->uri());
    dest.setHost(destination.host());
    dest.setPort(destination.port());
    dest.setScheme(destination.scheme());

    QNetworkRequest proxyReq(dest);

    const Headers reqHeaders = request->headers();
    const auto headersData = reqHeaders.data();
    auto it = headersData.constBegin();
    while (it != headersData.constEnd()) {
        proxyReq.setRawHeader(Cutelyst::Engine::camelCaseHeader(it.key()).toLatin1(), it.value().toLatin1());
        ++it;
    }

    return m_instance.sendCustomRequest(proxyReq, request->method().toLatin1(), request->body());
}

QNetworkReply *UA::forwardRequestResponse(Context *c, const QUrl &destination)
{
    QNetworkReply *reply = forwardRequest(c->request(), destination);
    QObject::connect(reply, &QNetworkReply::finished, c, [=] {
        Headers &responseHeaders = c->response()->headers();
        const QList<QNetworkReply::RawHeaderPair> &headers = reply->rawHeaderPairs();
        for (const QNetworkReply::RawHeaderPair &pair : headers) {
            responseHeaders.setHeader(QString::fromLatin1(pair.first), QString::fromLatin1(pair.second));
        }
        c->response()->setStatus(quint16(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt()));
        c->response()->setBody(reply);
    });
    return reply;
}

void UA::forwardAsync(Context *c, const QUrl &destination)
{
    QNetworkReply *reply = forwardRequest(c->request(), destination);
    QObject::connect(reply, &QNetworkReply::finished, c, [=] {
        Headers &responseHeaders = c->response()->headers();
        const QList<QNetworkReply::RawHeaderPair> &headers = reply->rawHeaderPairs();
        for (const QNetworkReply::RawHeaderPair &pair : headers) {
            responseHeaders.setHeader(QString::fromLatin1(pair.first), QString::fromLatin1(pair.second));
        }
        c->response()->setStatus(quint16(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toUInt()));
        c->response()->setBody(reply);
        c->attachAsync();
    });
    c->detachAsync();
}
<|endoftext|>


<commit_before>/**
  An implementation of Markov chains for text generation using C++11 and STL
  methods.

  Author: Bastian Rieck <bastian@rieck.ru>
*/

#include <algorithm>
#include <fstream>
#include <iterator>
#include <iostream>
#include <list>
#include <map>
#include <random>
#include <sstream>
#include <string>
#include <vector>

const std::string punctuation = ",;:.!?";
typedef std::map< std::string, std::vector<std::string> > database_type;

/**
  Tokenizes a given file. Any punctuation mark and any whitespace character is
  considered a token. The function returns a container of all tokens in the
  order in which they appear in the text. By concatenating subsequent  entries
  with a whitespace character, the original text may be formed again.
*/

std::vector<std::string> getTokens( const std::string& filename )
{
  std::ifstream in( filename );

  std::vector<std::string> rawTokens;

  std::copy(  std::istream_iterator<std::string>( in ),
              std::istream_iterator<std::string>(),
              std::back_inserter( rawTokens ) );

  std::vector<std::string> tokens;
  tokens.reserve( rawTokens.size() );

  for( auto&& rawToken : rawTokens )
  {
    // Only use the _last_ punctuation that may be found in the token. We do
    // not want to split a chapter number or a word.
    auto pos = rawToken.find_last_of( punctuation );
    if( pos != std::string::npos && pos + 1 == rawToken.length() )
    {
      tokens.push_back( rawToken.substr( 0, pos ) );
      tokens.push_back( rawToken.substr( pos ) );
    }

    // Simply copy the token
    else
      tokens.push_back( rawToken );
  }

  return tokens;
}

/**
  Joins a sequence of tokens and returns a single string. If one of the tokens
  is a punctuation mark, spurious punctuation will be avoided.
*/

template <class InputIterator> std::string join( InputIterator begin, InputIterator end )
{
  std::string result;

  for( auto it = begin; it != end; ++it )
  {
    // Is this punctuation? If so, do not add any whitespace.
    if( it->length() == 1 && it->find_first_of( punctuation ) != std::string::npos )
      result += *it;
    else
    {
      if( it != begin )
        result += " ";

      result += *it;
    }
  }

  return result;
}

/** Splits a string into its sequence of tokens. */
template <class OutputIterator> void split( const std::string& string, OutputIterator result )
{
  std::istringstream buffer( string );

  std::vector<std::string> rawTokens;

  std::copy(  std::istream_iterator<std::string>( buffer ),
              std::istream_iterator<std::string>(),
              std::back_inserter( rawTokens ) );

  for( auto&& rawToken : rawTokens )
  {
    // Only use the _last_ punctuation that may be found in the token. We do
    // not want to split a chapter number or a word.
    auto pos = rawToken.find_last_of( punctuation );
    if( rawToken.length() > 1 && pos != std::string::npos && pos + 1 == rawToken.length() )
    {
      *result++ = rawToken.substr( 0, pos );
      *result++ = rawToken.substr( pos );
    }

    // Simply copy the token
    else
      *result++ = rawToken;
  }
}

/**
  Given a vector of tokens and a prefix length, traverses the vector and stores
  the appropriate suffix of the token. The model for updating the suffixes is
  very simple --- subsequent words are merely added to a list of known words.
  This makes choosing the next word easier.
*/

database_type buildDatabase( const std::vector<std::string>& tokens, unsigned int prefixLength )
{
  database_type database;

  std::list<std::string> prefixWords( prefixLength );

  for( std::size_t i = 0; i < tokens.size(); i++ )
  {
    prefixWords.pop_front();
    prefixWords.push_back( tokens.at(i) );

    if( i + 1 < tokens.size() )
    {
      std::string prefix = join( prefixWords.begin(),
                                 prefixWords.end() );

      database[prefix].push_back( tokens.at(i+1) );
    }
  }

  return database;
}

/**
  Starts creating text from the database of tokens, using a Markov chain. The
  function will choose a prefix at random from the database, then select a
  subsequent word from the word list at random, thereby creating a new prefix.
  This process will be repeated until a number of pre-defined iterations has
  been reached.
*/

std::string spew( const database_type& database, unsigned int numIterations )
{
  std::random_device rd;
  std::default_random_engine engine( rd() );

  std::ostringstream output;
  std::string prefix;

  {
    std::uniform_int_distribution<std::size_t> distribution( 0, database.size() - 1 );
    std::size_t index = distribution( engine );
    auto it           = database.begin();

    std::advance( it, index );

    prefix = it->first;
    output << prefix;
  }

  for( unsigned int i = 1; i < numIterations; i++ )
  {
    auto&& words = database.at( prefix );

    std::uniform_int_distribution<std::size_t> distribution( 0, words.size() - 1 );
    std::size_t index = distribution( engine );
    std::string word  = words.at( index );

    // Choose a new prefix. We do this by splitting the old prefix into a list
    // of tokens, deleting the first one, and appending the current word.

    std::list<std::string> prefixTokens;
    split( prefix,
           std::back_inserter( prefixTokens ) );

    prefixTokens.pop_front();
    prefixTokens.push_back( word );

    prefix = join( prefixTokens.begin(), prefixTokens.end() );

    if( !( word.length() == 1 && word.find_first_of( punctuation ) != std::string::npos ) )
      output << " ";

    output << word;
  }

  return output.str();
}

int main( int, char** )
{
  auto tokens   = getTokens( "../King_James.txt" );
  auto database = buildDatabase( tokens, 2 );

  std::cout << spew( database, 100 );

  return 0;
}
<commit_msg>Added licence<commit_after>/*
 * An implementation of Markov chains for text generation using C++11 and STL
 * methods.
 *
 * Copyright (c) 2014 Bastian Rieck
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <algorithm>
#include <fstream>
#include <iterator>
#include <iostream>
#include <list>
#include <map>
#include <random>
#include <sstream>
#include <string>
#include <vector>

const std::string punctuation = ",;:.!?";
typedef std::map< std::string, std::vector<std::string> > database_type;

/**
  Tokenizes a given file. Any punctuation mark and any whitespace character is
  considered a token. The function returns a container of all tokens in the
  order in which they appear in the text. By concatenating subsequent  entries
  with a whitespace character, the original text may be formed again.
*/

std::vector<std::string> getTokens( const std::string& filename )
{
  std::ifstream in( filename );

  std::vector<std::string> rawTokens;

  std::copy(  std::istream_iterator<std::string>( in ),
              std::istream_iterator<std::string>(),
              std::back_inserter( rawTokens ) );

  std::vector<std::string> tokens;
  tokens.reserve( rawTokens.size() );

  for( auto&& rawToken : rawTokens )
  {
    // Only use the _last_ punctuation that may be found in the token. We do
    // not want to split a chapter number or a word.
    auto pos = rawToken.find_last_of( punctuation );
    if( pos != std::string::npos && pos + 1 == rawToken.length() )
    {
      tokens.push_back( rawToken.substr( 0, pos ) );
      tokens.push_back( rawToken.substr( pos ) );
    }

    // Simply copy the token
    else
      tokens.push_back( rawToken );
  }

  return tokens;
}

/**
  Joins a sequence of tokens and returns a single string. If one of the tokens
  is a punctuation mark, spurious punctuation will be avoided.
*/

template <class InputIterator> std::string join( InputIterator begin, InputIterator end )
{
  std::string result;

  for( auto it = begin; it != end; ++it )
  {
    // Is this punctuation? If so, do not add any whitespace.
    if( it->length() == 1 && it->find_first_of( punctuation ) != std::string::npos )
      result += *it;
    else
    {
      if( it != begin )
        result += " ";

      result += *it;
    }
  }

  return result;
}

/** Splits a string into its sequence of tokens. */
template <class OutputIterator> void split( const std::string& string, OutputIterator result )
{
  std::istringstream buffer( string );

  std::vector<std::string> rawTokens;

  std::copy(  std::istream_iterator<std::string>( buffer ),
              std::istream_iterator<std::string>(),
              std::back_inserter( rawTokens ) );

  for( auto&& rawToken : rawTokens )
  {
    // Only use the _last_ punctuation that may be found in the token. We do
    // not want to split a chapter number or a word.
    auto pos = rawToken.find_last_of( punctuation );
    if( rawToken.length() > 1 && pos != std::string::npos && pos + 1 == rawToken.length() )
    {
      *result++ = rawToken.substr( 0, pos );
      *result++ = rawToken.substr( pos );
    }

    // Simply copy the token
    else
      *result++ = rawToken;
  }
}

/**
  Given a vector of tokens and a prefix length, traverses the vector and stores
  the appropriate suffix of the token. The model for updating the suffixes is
  very simple --- subsequent words are merely added to a list of known words.
  This makes choosing the next word easier.
*/

database_type buildDatabase( const std::vector<std::string>& tokens, unsigned int prefixLength )
{
  database_type database;

  std::list<std::string> prefixWords( prefixLength );

  for( std::size_t i = 0; i < tokens.size(); i++ )
  {
    prefixWords.pop_front();
    prefixWords.push_back( tokens.at(i) );

    if( i + 1 < tokens.size() )
    {
      std::string prefix = join( prefixWords.begin(),
                                 prefixWords.end() );

      database[prefix].push_back( tokens.at(i+1) );
    }
  }

  return database;
}

/**
  Starts creating text from the database of tokens, using a Markov chain. The
  function will choose a prefix at random from the database, then select a
  subsequent word from the word list at random, thereby creating a new prefix.
  This process will be repeated until a number of pre-defined iterations has
  been reached.
*/

std::string spew( const database_type& database, unsigned int numIterations )
{
  std::random_device rd;
  std::default_random_engine engine( rd() );

  std::ostringstream output;
  std::string prefix;

  {
    std::uniform_int_distribution<std::size_t> distribution( 0, database.size() - 1 );
    std::size_t index = distribution( engine );
    auto it           = database.begin();

    std::advance( it, index );

    prefix = it->first;
    output << prefix;
  }

  for( unsigned int i = 1; i < numIterations; i++ )
  {
    auto&& words = database.at( prefix );

    std::uniform_int_distribution<std::size_t> distribution( 0, words.size() - 1 );
    std::size_t index = distribution( engine );
    std::string word  = words.at( index );

    // Choose a new prefix. We do this by splitting the old prefix into a list
    // of tokens, deleting the first one, and appending the current word.

    std::list<std::string> prefixTokens;
    split( prefix,
           std::back_inserter( prefixTokens ) );

    prefixTokens.pop_front();
    prefixTokens.push_back( word );

    prefix = join( prefixTokens.begin(), prefixTokens.end() );

    if( !( word.length() == 1 && word.find_first_of( punctuation ) != std::string::npos ) )
      output << " ";

    output << word;
  }

  return output.str();
}

int main( int, char** )
{
  auto tokens   = getTokens( "../King_James.txt" );
  auto database = buildDatabase( tokens, 2 );

  std::cout << spew( database, 100 );

  return 0;
}
<|endoftext|>


<commit_before>#include "main.h"

/* example constructor, sets some options */
CaesarAttack::CaesarAttack()
{
    // declare options, keep options as uppercase
    vector<string> temp;
    temp.push_back("INPUTFILE");
    temp.push_back("OUTPUTFILE");
    set_opts(temp);

    // set default values, option must exist or error will printed
    set_opt_value("OUTPUTFILE", "/tmp/caesarattackresults.txt");
}

/* I am overriding the default module function
 * for displaying the description text
 */
void CaesarAttack::disp_desc()
{
    cout << "Module: attacks/caesar_attack\n\tThis module attempts to guess the correct shift for the Caesar cipher.\n\tIt makes use of frequency analysis to determine a proper guess.\n\tMay require user interaction.\n\tPlease define an INPUTFILE." << endl;
    cout << endl;
}

/* overrides the virtual function from Module
 * this is where the real meaty stuff happens
 */
int CaesarAttack::run()
{
    // perform error checking on options first
    if (options["INPUTFILE"].empty()) {
        cout << "[-] Please specify an input file" << endl;
        return 1;
    }

    if (options["OUTPUTFILE"].empty()) {
        cout << "[-] Please specify an output file" << endl;
        return 2;
    }

    ifstream in;
    ofstream out;
    string buff;

    cout << "[*] Opening input file: " << options["INPUTFILE"] << endl;
    in.open(options["INPUTFILE"]);

    cout << "[*] Beginning attack..." << endl;
    begin_attack(in, out);

    cout << "[*] Closing files" << endl;
    in.close();
    out.close();

    return 0;
}

/* not safe helper function
 * doesn't check array out of bounds
 */
float chisq(float *y, float *ym)
{
    float sq = 0.0f;
    for (int i = 0; i < 26; i++)
        sq += (y[i] - ym[i])*(y[i] - ym[i]);
    return sq;
}

/* shifts each entry to the left one */
void left_shift_freq(float *freq)
{
    float temp = freq[0];
    for (int i = 0; i < 25; i++)
        freq[i] = freq[i+1];
    freq[26] = temp;
}

/* handles the main attack sequence */
void CaesarAttack::begin_attack(ifstream &in, ofstream &out)
{
    /* from analyzing huckleberry finn */
    float english[] = {0.0834423, 0.0169666, 0.0191698, 0.0539923, 0.112034, 0.0180501, 0.0246394, 0.0602159, 0.0646833, 0.00280142, 0.0130094, 0.0398317, 0.0236778, 0.0747964, 0.0835958, 0.0138107, 0.000442449, 0.0464413, 0.057629, 0.0967157, 0.0318857, 0.00675638, 0.03031, 0.0011919, 0.0234859, 0.00042439};

    int freq[26] = {0}, count = 0;
    float ffreq[26] = {0.0f};
    string buff;

    while (getline(in, buff)) {
        for (unsigned int i = 0; i < buff.size(); i++) {
            if (isalpha(buff[i])) {
                int t = ((int) tolower(buff[i])) - 97;
                freq[t]++; count++;
            }
        }
    }

    for (int i = 0; i < 26; i++)
        ffreq[i] = (float)freq[i]/(float)count;

    int mins[26]; float csq[26];
    for (int i = 0; i < 26; i++) {
        mins[i] = i;
        csq[i] = chisq(ffreq, english);
        left_shift_freq(ffreq);
    }

    /* insertion sort */
    for (int i = 0; i < 26; i++) {
        int j = i;
        while (j > 0 && csq[mins[j-1]] > csq[mins[j]]) {
            int temp = mins[j-1];
            mins[j-1] = mins[j];
            mins[j] = temp;
            j--;
        }
    }

    // for (int i = 0; i < 26; i++)
    //     cout << "\t" << mins[i] << "\t" << csq[mins[i]] << endl;

    string ans;
    cout << "[+] Most likely shift: " << mins[0] << endl;

    for (int i = 0; i < 26; i++) {
        cout << "[*] Decrypting file with shift " << mins[i] << " (chi^2 = " << csq[mins[i]] << ")..." << endl;

        out.open(options["OUTPUTFILE"]);

        // reset input
        in.clear();
        in.seekg(0);

        string obuff;
        int samplecount = 0;
        cout << "[*] Sample from decryption: " << endl;
        while (getline(in, buff)) {
            Caesar::encrypt(buff, obuff, mins[i], true);
            out << obuff << endl;
            if (samplecount < 5) {
                cout << obuff << endl;
                samplecount++;
            } else {
                break;
            }
        }

        string ans;
        cout << "[*] Continue decryption? [Y/n]: ";
        getline(cin, ans);
        if (ans == "N" || ans == "n")
            continue;

        while (getline(in, buff)) {
            Caesar::encrypt(buff, obuff, mins[i], true);
            out << obuff << endl;
        }

        // if we get here we are done
        break;
    }
}
<commit_msg>added guess based on e frequency as first resort<commit_after>#include "main.h"

/* example constructor, sets some options */
CaesarAttack::CaesarAttack()
{
    // declare options, keep options as uppercase
    vector<string> temp;
    temp.push_back("INPUTFILE");
    temp.push_back("OUTPUTFILE");
    set_opts(temp);

    // set default values, option must exist or error will printed
    set_opt_value("OUTPUTFILE", "/tmp/caesarattackresults.txt");
}

/* I am overriding the default module function
 * for displaying the description text
 */
void CaesarAttack::disp_desc()
{
    cout << "Module: attacks/caesar_attack\n\tThis module attempts to guess the correct shift for the Caesar cipher.\n\tIt makes use of frequency analysis to determine a proper guess.\n\tMay require user interaction.\n\tPlease define an INPUTFILE." << endl;
    cout << endl;
}

/* overrides the virtual function from Module
 * this is where the real meaty stuff happens
 */
int CaesarAttack::run()
{
    // perform error checking on options first
    if (options["INPUTFILE"].empty()) {
        cout << "[-] Please specify an input file" << endl;
        return 1;
    }

    if (options["OUTPUTFILE"].empty()) {
        cout << "[-] Please specify an output file" << endl;
        return 2;
    }

    ifstream in;
    ofstream out;
    string buff;

    cout << "[*] Opening input file: " << options["INPUTFILE"] << endl;
    in.open(options["INPUTFILE"]);

    cout << "[*] Beginning attack..." << endl;
    begin_attack(in, out);

    cout << "[*] Closing files" << endl;
    in.close();
    out.close();

    return 0;
}

/* not safe helper function
 * doesn't check array out of bounds
 */
float chisq(float *y, float *ym)
{
    float sq = 0.0f;
    for (int i = 0; i < 26; i++)
        sq += (y[i] - ym[i])*(y[i] - ym[i]);
    return sq;
}

/* shifts each entry to the left one */
void left_shift_freq(float *freq)
{
    float temp = freq[0];
    for (int i = 0; i < 25; i++)
        freq[i] = freq[i+1];
    freq[26] = temp;
}

/* handles the main attack sequence */
void CaesarAttack::begin_attack(ifstream &in, ofstream &out)
{
    /* from analyzing huckleberry finn */
    float english[] = {0.0834423, 0.0169666, 0.0191698, 0.0539923, 0.112034, 0.0180501, 0.0246394, 0.0602159, 0.0646833, 0.00280142, 0.0130094, 0.0398317, 0.0236778, 0.0747964, 0.0835958, 0.0138107, 0.000442449, 0.0464413, 0.057629, 0.0967157, 0.0318857, 0.00675638, 0.03031, 0.0011919, 0.0234859, 0.00042439};

    int freq[26] = {0}, count = 0;
    float ffreq[26] = {0.0f};
    string buff;

    while (getline(in, buff)) {
        for (unsigned int i = 0; i < buff.size(); i++) {
            if (isalpha(buff[i])) {
                int t = ((int) tolower(buff[i])) - 97;
                freq[t]++; count++;
            }
        }
    }

    for (int i = 0; i < 26; i++)
        ffreq[i] = (float)freq[i]/(float)count;

    int max = 0;
    for (int j = 1; j < 26; j++)
        if (ffreq[j] > ffreq[max])
            max = j;
    int maxkey = (max-4 < 0) ? max-4+26 : max-4;
    cout << "[*] Guessing based on 'e' frequency" << endl;
    cout << "[*] Decrypting file with shift " << maxkey << "..." << endl;

    out.open(options["OUTPUTFILE"]);

    // reset input
    in.clear();
    in.seekg(0);

    string obuff;
    int samplecount = 0;
    cout << "[*] Sample from decryption: " << endl;
    while (getline(in, buff)) {
        Caesar::encrypt(buff, obuff, maxkey, true);
        out << obuff << endl;
        if (samplecount < 5) {
            cout << obuff << endl;
            samplecount++;
        } else {
            break;
        }
    }

    string ans;
    cout << "[*] Continue decryption? [Y/n]: ";
    getline(cin, ans);
    if (ans == "Y" || ans == "y") {
        while (getline(in, buff)) {
            Caesar::encrypt(buff, obuff, maxkey, true);
            out << obuff << endl;
        }

        return;
    }

    out.close();
    cout << "[*] Falling back to chi^2 analysis..." << endl;

    int mins[26]; float csq[26];
    for (int i = 0; i < 26; i++) {
        mins[i] = i;
        csq[i] = chisq(ffreq, english);
        left_shift_freq(ffreq);
    }

    /* insertion sort */
    for (int i = 0; i < 26; i++) {
        int j = i;
        while (j > 0 && csq[mins[j-1]] > csq[mins[j]]) {
            int temp = mins[j-1];
            mins[j-1] = mins[j];
            mins[j] = temp;
            j--;
        }
    }

    cout << "[+] Most likely shift: " << mins[0] << endl;

    for (int i = 0; i < 26; i++) {
        cout << "[*] Decrypting file with shift " << mins[i] << " (chi^2 = " << csq[mins[i]] << ")..." << endl;

        out.open(options["OUTPUTFILE"]);

        // reset input
        in.clear();
        in.seekg(0);

        string obuff;
        int samplecount = 0;
        cout << "[*] Sample from decryption: " << endl;
        while (getline(in, buff)) {
            Caesar::encrypt(buff, obuff, mins[i], true);
            out << obuff << endl;
            if (samplecount < 5) {
                cout << obuff << endl;
                samplecount++;
            } else {
                break;
            }
        }

        string ans;
        cout << "[*] Continue decryption? [Y/n]: ";
        getline(cin, ans);
        if (ans == "N" || ans == "n") {
            out.close();
            continue;
        }

        while (getline(in, buff)) {
            Caesar::encrypt(buff, obuff, mins[i], true);
            out << obuff << endl;
        }

        // if we get here we are done
        break;
    }
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2020, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. Neither the name of the copyright holder 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 HOLDER 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.
 */

#include "web/web-service/ot_client.hpp"

#include <openthread/platform/toolchain.h>

#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include "common/code_utils.hpp"
#include "common/logging.hpp"
#include "utils/strcpy_utils.hpp"

// Temporary solution before posix platform header files are cleaned up.
#ifndef OPENTHREAD_POSIX_APP_SOCKET_NAME
#define OPENTHREAD_POSIX_APP_SOCKET_NAME "/tmp/openthread.sock"
#endif

namespace otbr {
namespace Web {

OpenThreadClient::OpenThreadClient(void)
    : mTimeout(kDefaultTimeout)
    , mSocket(-1)
{
}

OpenThreadClient::~OpenThreadClient(void)
{
    Disconnect();
}

void OpenThreadClient::Disconnect(void)
{
    if (mSocket != -1)
    {
        close(mSocket);
        mSocket = -1;
    }
}

bool OpenThreadClient::Connect(void)
{
    struct sockaddr_un sockname;
    int                ret;

    mSocket = socket(AF_UNIX, SOCK_STREAM, 0);
    VerifyOrExit(mSocket != -1, perror("socket"); ret = EXIT_FAILURE);

    memset(&sockname, 0, sizeof(struct sockaddr_un));
    sockname.sun_family = AF_UNIX;
    strcpy_safe(sockname.sun_path, sizeof(sockname.sun_path), OPENTHREAD_POSIX_APP_SOCKET_NAME);

    ret = connect(mSocket, reinterpret_cast<const struct sockaddr *>(&sockname), sizeof(struct sockaddr_un));

    if (ret == -1)
    {
        otbrLog(OTBR_LOG_ERR, "OpenThread daemon is not running.");
    }

exit:
    return ret == 0;
}

char *OpenThreadClient::Execute(const char *aFormat, ...)
{
    va_list args;
    int     ret;
    char *  rval = nullptr;
    ssize_t count;
    size_t  rxLength = 0;

    va_start(args, aFormat);
    ret = vsnprintf(&mBuffer[1], sizeof(mBuffer) - 1, aFormat, args);
    va_end(args);

    if (ret < 0)
    {
        otbrLog(OTBR_LOG_ERR, "Failed to generate command: %s", strerror(errno));
    }

    mBuffer[0] = '\n';
    ret++;

    if (ret == sizeof(mBuffer))
    {
        otbrLog(OTBR_LOG_ERR, "Command exceeds maximum limit: %d", kBufferSize);
    }

    mBuffer[ret] = '\n';
    ret++;

    count = write(mSocket, mBuffer, ret);

    if (count < ret)
    {
        mBuffer[ret] = '\0';
        otbrLog(OTBR_LOG_ERR, "Failed to send command: %s", mBuffer);
    }

    for (int i = 0; i < mTimeout; ++i)
    {
        fd_set  readFdSet;
        timeval timeout = {0, 1000};
        char *  done;

        FD_ZERO(&readFdSet);
        FD_SET(mSocket, &readFdSet);

        ret = select(mSocket + 1, &readFdSet, nullptr, nullptr, &timeout);
        VerifyOrExit(ret != -1 || errno == EINTR);
        if (ret <= 0)
        {
            continue;
        }

        count = read(mSocket, &mBuffer[rxLength], sizeof(mBuffer) - rxLength);
        VerifyOrExit(count > 0);
        rxLength += count;

        mBuffer[rxLength] = '\0';
        done              = strstr(mBuffer, "Done\r\n");

        if (done != nullptr)
        {
            // remove trailing \r\n
            if (done - rval > 2)
            {
                done[-2] = '\0';
            }

            rval = mBuffer;
            break;
        }
    }

exit:
    return rval;
}

int OpenThreadClient::Scan(WpanNetworkInfo *aNetworks, int aLength)
{
    char *result;
    int   rval = 0;

    mTimeout = 5000;
    result   = Execute("scan");
    VerifyOrExit(result != nullptr);

    for (result = strtok(result, "\r\n"); result != nullptr && rval < aLength; result = strtok(nullptr, "\r\n"))
    {
        static const char kCliPrompt[] = "> ";
        char *            cliPrompt;
        int               matched;
        int               joinable;
        int               lqi;

        // remove prompt
        if ((cliPrompt = strstr(result, kCliPrompt)) != nullptr)
        {
            if (cliPrompt == result)
            {
                result += sizeof(kCliPrompt) - 1;
            }
            else
            {
                memmove(cliPrompt, cliPrompt + sizeof(kCliPrompt) - 1, strlen(cliPrompt) - sizeof(kCliPrompt) - 1);
            }
        }

        matched = sscanf(result,
                         "| %d | %s | %" PRIx64
                         " | %hx | %02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx | %hu | %hhd | %d |",
                         &joinable, aNetworks[rval].mNetworkName, &aNetworks[rval].mExtPanId, &aNetworks[rval].mPanId,
                         &aNetworks[rval].mHardwareAddress[0], &aNetworks[rval].mHardwareAddress[1],
                         &aNetworks[rval].mHardwareAddress[2], &aNetworks[rval].mHardwareAddress[3],
                         &aNetworks[rval].mHardwareAddress[4], &aNetworks[rval].mHardwareAddress[5],
                         &aNetworks[rval].mHardwareAddress[6], &aNetworks[rval].mHardwareAddress[7],
                         &aNetworks[rval].mChannel, &aNetworks[rval].mRssi, &lqi);

        // 15 is the number of output arguments of the last sscanf()
        if (matched != 15)
        {
            continue;
        }

        aNetworks[rval].mAllowingJoin = joinable != 0;
        ++rval;
    }

    mTimeout = kDefaultTimeout;

exit:
    return rval;
}

bool OpenThreadClient::FactoryReset(void)
{
    const char *result;
    bool        rval = false;
#if __APPLE__
    typedef sig_t sighandler_t;
#endif
    sighandler_t handler;

    // Ignore the expected SIGPIPE signal during daemon reset.
    handler = signal(SIGPIPE, SIG_IGN);
    Execute("factoryreset");
    signal(SIGPIPE, handler);
    Disconnect();
    sleep(1);
    VerifyOrExit(rval = Connect());

    result = Execute("version");
    VerifyOrExit(result != nullptr);

    rval = strstr(result, "OPENTHREAD") != nullptr;

exit:
    return rval;
}

} // namespace Web
} // namespace otbr
<commit_msg>[ot-client] fix bug in stripping `Done\r\n` (#781)<commit_after>/*
 *  Copyright (c) 2020, The OpenThread Authors.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. 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.
 *  3. Neither the name of the copyright holder 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 HOLDER 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.
 */

#include "web/web-service/ot_client.hpp"

#include <openthread/platform/toolchain.h>

#include <errno.h>
#include <inttypes.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include "common/code_utils.hpp"
#include "common/logging.hpp"
#include "utils/strcpy_utils.hpp"

// Temporary solution before posix platform header files are cleaned up.
#ifndef OPENTHREAD_POSIX_APP_SOCKET_NAME
#define OPENTHREAD_POSIX_APP_SOCKET_NAME "/tmp/openthread.sock"
#endif

namespace otbr {
namespace Web {

OpenThreadClient::OpenThreadClient(void)
    : mTimeout(kDefaultTimeout)
    , mSocket(-1)
{
}

OpenThreadClient::~OpenThreadClient(void)
{
    Disconnect();
}

void OpenThreadClient::Disconnect(void)
{
    if (mSocket != -1)
    {
        close(mSocket);
        mSocket = -1;
    }
}

bool OpenThreadClient::Connect(void)
{
    struct sockaddr_un sockname;
    int                ret;

    mSocket = socket(AF_UNIX, SOCK_STREAM, 0);
    VerifyOrExit(mSocket != -1, perror("socket"); ret = EXIT_FAILURE);

    memset(&sockname, 0, sizeof(struct sockaddr_un));
    sockname.sun_family = AF_UNIX;
    strcpy_safe(sockname.sun_path, sizeof(sockname.sun_path), OPENTHREAD_POSIX_APP_SOCKET_NAME);

    ret = connect(mSocket, reinterpret_cast<const struct sockaddr *>(&sockname), sizeof(struct sockaddr_un));

    if (ret == -1)
    {
        otbrLog(OTBR_LOG_ERR, "OpenThread daemon is not running.");
    }

exit:
    return ret == 0;
}

char *OpenThreadClient::Execute(const char *aFormat, ...)
{
    va_list args;
    int     ret;
    char *  rval = nullptr;
    ssize_t count;
    size_t  rxLength = 0;

    va_start(args, aFormat);
    ret = vsnprintf(&mBuffer[1], sizeof(mBuffer) - 1, aFormat, args);
    va_end(args);

    if (ret < 0)
    {
        otbrLog(OTBR_LOG_ERR, "Failed to generate command: %s", strerror(errno));
    }

    mBuffer[0] = '\n';
    ret++;

    if (ret == sizeof(mBuffer))
    {
        otbrLog(OTBR_LOG_ERR, "Command exceeds maximum limit: %d", kBufferSize);
    }

    mBuffer[ret] = '\n';
    ret++;

    count = write(mSocket, mBuffer, ret);

    if (count < ret)
    {
        mBuffer[ret] = '\0';
        otbrLog(OTBR_LOG_ERR, "Failed to send command: %s", mBuffer);
    }

    for (int i = 0; i < mTimeout; ++i)
    {
        fd_set  readFdSet;
        timeval timeout = {0, 1000};
        char *  done;

        FD_ZERO(&readFdSet);
        FD_SET(mSocket, &readFdSet);

        ret = select(mSocket + 1, &readFdSet, nullptr, nullptr, &timeout);
        VerifyOrExit(ret != -1 || errno == EINTR);
        if (ret <= 0)
        {
            continue;
        }

        count = read(mSocket, &mBuffer[rxLength], sizeof(mBuffer) - rxLength);
        VerifyOrExit(count > 0);
        rxLength += count;

        mBuffer[rxLength] = '\0';
        done              = strstr(mBuffer, "Done\r\n");

        if (done != nullptr)
        {
            // remove trailing \r\n
            if (done - mBuffer > 2)
            {
                done[-2] = '\0';
            }

            rval = mBuffer;
            break;
        }
    }

exit:
    return rval;
}

int OpenThreadClient::Scan(WpanNetworkInfo *aNetworks, int aLength)
{
    char *result;
    int   rval = 0;

    mTimeout = 5000;
    result   = Execute("scan");
    VerifyOrExit(result != nullptr);

    for (result = strtok(result, "\r\n"); result != nullptr && rval < aLength; result = strtok(nullptr, "\r\n"))
    {
        static const char kCliPrompt[] = "> ";
        char *            cliPrompt;
        int               matched;
        int               joinable;
        int               lqi;

        // remove prompt
        if ((cliPrompt = strstr(result, kCliPrompt)) != nullptr)
        {
            if (cliPrompt == result)
            {
                result += sizeof(kCliPrompt) - 1;
            }
            else
            {
                memmove(cliPrompt, cliPrompt + sizeof(kCliPrompt) - 1, strlen(cliPrompt) - sizeof(kCliPrompt) - 1);
            }
        }

        matched = sscanf(result,
                         "| %d | %s | %" PRIx64
                         " | %hx | %02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx | %hu | %hhd | %d |",
                         &joinable, aNetworks[rval].mNetworkName, &aNetworks[rval].mExtPanId, &aNetworks[rval].mPanId,
                         &aNetworks[rval].mHardwareAddress[0], &aNetworks[rval].mHardwareAddress[1],
                         &aNetworks[rval].mHardwareAddress[2], &aNetworks[rval].mHardwareAddress[3],
                         &aNetworks[rval].mHardwareAddress[4], &aNetworks[rval].mHardwareAddress[5],
                         &aNetworks[rval].mHardwareAddress[6], &aNetworks[rval].mHardwareAddress[7],
                         &aNetworks[rval].mChannel, &aNetworks[rval].mRssi, &lqi);

        // 15 is the number of output arguments of the last sscanf()
        if (matched != 15)
        {
            continue;
        }

        aNetworks[rval].mAllowingJoin = joinable != 0;
        ++rval;
    }

    mTimeout = kDefaultTimeout;

exit:
    return rval;
}

bool OpenThreadClient::FactoryReset(void)
{
    const char *result;
    bool        rval = false;
#if __APPLE__
    typedef sig_t sighandler_t;
#endif
    sighandler_t handler;

    // Ignore the expected SIGPIPE signal during daemon reset.
    handler = signal(SIGPIPE, SIG_IGN);
    Execute("factoryreset");
    signal(SIGPIPE, handler);
    Disconnect();
    sleep(1);
    VerifyOrExit(rval = Connect());

    result = Execute("version");
    VerifyOrExit(result != nullptr);

    rval = strstr(result, "OPENTHREAD") != nullptr;

exit:
    return rval;
}

} // namespace Web
} // namespace otbr
<|endoftext|>


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

#include <Observation.hpp>
#include <ReadData.hpp>
#include <string>
#include <vector>
#include <gtest/gtest.h>

TEST(ZappedChannels, FileError)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    std::string wrongFileName = "./zappred_channels.conf";
    ASSERT_THROW(AstroData::readZappedChannels(observation, wrongFileName, channels), AstroData::FileError);
}

TEST(ZappedChannels, MatchingChannels)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    std::string fileName = "./zapped_channels.conf";
    observation.setFrequencyRange(1, 1024, 0.0f, 0.0f);
    channels.resize(observation.getNrChannels());
    AstroData::readZappedChannels(observation, fileName, channels);
    EXPECT_EQ(channels.at(4), 1);
    EXPECT_EQ(channels.at(39), 1);
    EXPECT_EQ(channels.at(7), 1);
    EXPECT_EQ(channels.at(19), 1);
    EXPECT_EQ(channels.at(1023), 1);
    EXPECT_EQ(channels.at(0), 1);
    EXPECT_EQ(channels.at(45), 0);
    EXPECT_EQ(channels.at(128), 0);
}
<commit_msg>Updated the test.<commit_after>// Copyright 2019 Netherlands eScience Center and Netherlands Institute for Radio Astronomy (ASTRON)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <Observation.hpp>
#include <ReadData.hpp>
#include <string>
#include <vector>
#include <gtest/gtest.h>

TEST(ZappedChannels, FileError)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    std::string wrongFileName = "./zappred_channels.conf";
    ASSERT_THROW(AstroData::readZappedChannels(observation, wrongFileName, channels), AstroData::FileError);
}

TEST(ZappedChannels, MatchingChannels)
{
    AstroData::Observation observation;
    std::vector<unsigned int> channels;
    std::string fileName = "./zapped_channels.conf";
    observation.setFrequencyRange(1, 1024, 0.0f, 0.0f);
    channels.resize(observation.getNrChannels());
    AstroData::readZappedChannels(observation, fileName, channels);
    EXPECT_EQ(channels.at(4), 1);
    EXPECT_EQ(channels.at(39), 1);
    EXPECT_EQ(channels.at(7), 1);
    EXPECT_EQ(channels.at(19), 1);
    EXPECT_EQ(channels.at(1023), 1);
    EXPECT_EQ(channels.at(0), 1);
    EXPECT_NE(channels.at(45), 1);
    EXPECT_NE(channels.at(128), 1);
}
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/dim4.hpp>
#include <af/defines.h>
#include <ArrayInfo.hpp>
#include <Array.hpp>
#include <bilateral.hpp>
#include <cmath>
#include <algorithm>

using af::dim4;

namespace cpu
{

static inline dim_t clamp(int a, dim_t mn, dim_t mx)
{
    return (a < (int)mn ? mn : (a > (int)mx ? mx : a));
}

static inline unsigned getIdx(const dim4 &strides,
        int i, int j = 0, int k = 0, int l = 0)
{
    return (l * strides[3] +
            k * strides[2] +
            j * strides[1] +
            i * strides[0]);
}

template<typename inType, typename outType, bool isColor>
Array<outType> bilateral(const Array<inType> &in, const float &s_sigma, const float &c_sigma)
{
    const dim4 dims     = in.dims();
    const dim4 istrides = in.strides();

    Array<outType> out = createEmptyArray<outType>(dims);
    const dim4 ostrides = out.strides();

    outType *outData    = out.get();
    const inType * inData = in.get();

    // clamp spatical and chromatic sigma's
    float space_          = std::min(11.5f, std::max(s_sigma, 0.f));
    float color_          = std::max(c_sigma, 0.f);
    const dim_t radius = std::max((dim_t)(space_ * 1.5f), (dim_t)1);
    const float svar      = space_*space_;
    const float cvar      = color_*color_;

    for(dim_t b3=0; b3<dims[3]; ++b3) {
        // b3 for loop handles following batch configurations
        //  - gfor
        //  - input based batch
        //      - when input is 4d array for color images
        for(dim_t b2=0; b2<dims[2]; ++b2) {
            // b2 for loop handles following batch configurations
            //  - channels
            //  - input based batch
            //      - when input is 3d array for grayscale images
            for(dim_t j=0; j<dims[1]; ++j) {
                // j steps along 2nd dimension
                for(dim_t i=0; i<dims[0]; ++i) {
                    // i steps along 1st dimension
                    outType norm = 0.0;
                    outType res  = 0.0;
                    const outType center = (outType)inData[getIdx(istrides, i, j)];
                    for(dim_t wj=-radius; wj<=radius; ++wj) {
                        // clamps offsets
                        dim_t tj = clamp(j+wj, 0, dims[1]-1);
                        for(dim_t wi=-radius; wi<=radius; ++wi) {
                            // clamps offsets
                            dim_t ti = clamp(i+wi, 0, dims[0]-1);
                            // proceed
                            const outType val= (outType)inData[getIdx(istrides, ti, tj)];
                            const outType gauss_space = (wi*wi+wj*wj)/(-2.0*svar);
                            const outType gauss_range = ((center-val)*(center-val))/(-2.0*cvar);
                            const outType weight = std::exp(gauss_space+gauss_range);
                            norm += weight;
                            res += val*weight;
                        }
                    } // filter loop ends here

                    outData[getIdx(ostrides, i, j)] = res/norm;
                } //1st dimension loop ends here
            } //2nd dimension loop ends here
            outData += ostrides[2];
            inData  += istrides[2];
        }
    }

    return out;
}

#define INSTANTIATE(inT, outT)\
template Array<outT> bilateral<inT, outT,true >(const Array<inT> &in, const float &s_sigma, const float &c_sigma);\
template Array<outT> bilateral<inT, outT,false>(const Array<inT> &in, const float &s_sigma, const float &c_sigma);

INSTANTIATE(double, double)
INSTANTIATE(float ,  float)
INSTANTIATE(char  ,  float)
INSTANTIATE(int   ,  float)
INSTANTIATE(uint  ,  float)
INSTANTIATE(uchar ,  float)

}
<commit_msg>Async CPU Bilateral<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <af/dim4.hpp>
#include <af/defines.h>
#include <ArrayInfo.hpp>
#include <Array.hpp>
#include <bilateral.hpp>
#include <cmath>
#include <algorithm>
#include <platform.hpp>
#include <async_queue.hpp>

using af::dim4;
using std::ref;

namespace cpu
{

static inline dim_t clamp(int a, dim_t mn, dim_t mx)
{
    return (a < (int)mn ? mn : (a > (int)mx ? mx : a));
}

static inline unsigned getIdx(const dim4 &strides,
        int i, int j = 0, int k = 0, int l = 0)
{
    return (l * strides[3] +
            k * strides[2] +
            j * strides[1] +
            i * strides[0]);
}

template<typename inType, typename outType, bool isColor>
void bilateral_(Array<outType> out, const Array<inType> &in, float s_sigma, float c_sigma)
{
    const dim4 dims     = in.dims();
    const dim4 istrides = in.strides();

    const dim4 ostrides = out.strides();

    outType *outData    = out.get();
    const inType * inData = in.get();

    // clamp spatical and chromatic sigma's
    float space_          = std::min(11.5f, std::max(s_sigma, 0.f));
    float color_          = std::max(c_sigma, 0.f);
    const dim_t radius = std::max((dim_t)(space_ * 1.5f), (dim_t)1);
    const float svar      = space_*space_;
    const float cvar      = color_*color_;

    for(dim_t b3=0; b3<dims[3]; ++b3) {
        // b3 for loop handles following batch configurations
        //  - gfor
        //  - input based batch
        //      - when input is 4d array for color images
        for(dim_t b2=0; b2<dims[2]; ++b2) {
            // b2 for loop handles following batch configurations
            //  - channels
            //  - input based batch
            //      - when input is 3d array for grayscale images
            for(dim_t j=0; j<dims[1]; ++j) {
                // j steps along 2nd dimension
                for(dim_t i=0; i<dims[0]; ++i) {
                    // i steps along 1st dimension
                    outType norm = 0.0;
                    outType res  = 0.0;
                    const outType center = (outType)inData[getIdx(istrides, i, j)];
                    for(dim_t wj=-radius; wj<=radius; ++wj) {
                        // clamps offsets
                        dim_t tj = clamp(j+wj, 0, dims[1]-1);
                        for(dim_t wi=-radius; wi<=radius; ++wi) {
                            // clamps offsets
                            dim_t ti = clamp(i+wi, 0, dims[0]-1);
                            // proceed
                            const outType val= (outType)inData[getIdx(istrides, ti, tj)];
                            const outType gauss_space = (wi*wi+wj*wj)/(-2.0*svar);
                            const outType gauss_range = ((center-val)*(center-val))/(-2.0*cvar);
                            const outType weight = std::exp(gauss_space+gauss_range);
                            norm += weight;
                            res += val*weight;
                        }
                    } // filter loop ends here

                    outData[getIdx(ostrides, i, j)] = res/norm;
                } //1st dimension loop ends here
            } //2nd dimension loop ends here
            outData += ostrides[2];
            inData  += istrides[2];
        }
    }
}

template<typename inType, typename outType, bool isColor>
Array<outType> bilateral(const Array<inType> &in, const float &s_sigma, const float &c_sigma)
{
    const dim4 dims     = in.dims();
    Array<outType> out = createEmptyArray<outType>(dims);
    getQueue().enqueue(bilateral_<inType, outType, isColor>, out, ref(in), s_sigma, c_sigma);
    return out;
}

#define INSTANTIATE(inT, outT)\
template Array<outT> bilateral<inT, outT,true >(const Array<inT> &in, const float &s_sigma, const float &c_sigma);\
template Array<outT> bilateral<inT, outT,false>(const Array<inT> &in, const float &s_sigma, const float &c_sigma);

INSTANTIATE(double, double)
INSTANTIATE(float ,  float)
INSTANTIATE(char  ,  float)
INSTANTIATE(int   ,  float)
INSTANTIATE(uint  ,  float)
INSTANTIATE(uchar ,  float)

}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht // Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <cmath>

#include "catch.hpp"
#include "template_test.hpp"

#include "etl/etl.hpp"

TEMPLATE_TEST_CASE_2( "column_major/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 2, 3> test_matrix(0);

    REQUIRE(test_matrix.size() == 6);

    REQUIRE(test_matrix.template dim<0>() == 2);
    REQUIRE(test_matrix.template dim<1>() == 3);
    REQUIRE(test_matrix.dim(0) == 2);
    REQUIRE(test_matrix.dim(1) == 3);

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0) == 1);
    REQUIRE(test_matrix(0, 1) == 3);
    REQUIRE(test_matrix(0, 2) == 5);
    REQUIRE(test_matrix(1, 0) == 2);
    REQUIRE(test_matrix(1, 1) == 4);
    REQUIRE(test_matrix(1, 2) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/2", "[dyn][cm]", Z, int, long ) {
    etl::dyn_matrix_cm<Z> test_matrix(2, 3);

    test_matrix = 0;

    REQUIRE(test_matrix.size() == 6);

    REQUIRE(test_matrix.template dim<0>() == 2);
    REQUIRE(test_matrix.template dim<1>() == 3);
    REQUIRE(test_matrix.dim(0) == 2);
    REQUIRE(test_matrix.dim(1) == 3);

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0) == 1);
    REQUIRE(test_matrix(0, 1) == 3);
    REQUIRE(test_matrix(0, 2) == 5);
    REQUIRE(test_matrix(1, 0) == 2);
    REQUIRE(test_matrix(1, 1) == 4);
    REQUIRE(test_matrix(1, 2) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/3", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 2, 3, 4> test_matrix;

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0, 0) == 1);
    REQUIRE(test_matrix(0, 0, 1) == 7);
    REQUIRE(test_matrix(0, 0, 2) == 13);
    REQUIRE(test_matrix(0, 0, 3) == 19);
    REQUIRE(test_matrix(0, 1, 0) == 3);
    REQUIRE(test_matrix(0, 1, 1) == 9);
    REQUIRE(test_matrix(0, 1, 2) == 15);
    REQUIRE(test_matrix(0, 1, 3) == 21);
    REQUIRE(test_matrix(0, 2, 0) == 5);
    REQUIRE(test_matrix(0, 2, 1) == 11);
    REQUIRE(test_matrix(0, 2, 2) == 17);
    REQUIRE(test_matrix(0, 2, 3) == 23);
    REQUIRE(test_matrix(1, 0, 0) == 2);
    REQUIRE(test_matrix(1, 0, 1) == 8);
    REQUIRE(test_matrix(1, 0, 2) == 14);
    REQUIRE(test_matrix(1, 0, 3) == 20);
    REQUIRE(test_matrix(1, 1, 0) == 4);
    REQUIRE(test_matrix(1, 1, 1) == 10);
    REQUIRE(test_matrix(1, 1, 2) == 16);
    REQUIRE(test_matrix(1, 1, 3) == 22);
    REQUIRE(test_matrix(1, 2, 0) == 6);
    REQUIRE(test_matrix(1, 2, 1) == 12);
    REQUIRE(test_matrix(1, 2, 2) == 18);
    REQUIRE(test_matrix(1, 2, 3) == 24);
}

TEMPLATE_TEST_CASE_2( "column_major/4", "[dyn][cm]", Z, int, long ) {
    etl::dyn_matrix_cm<Z, 3> test_matrix(2, 3, 4);

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0, 0) == 1);
    REQUIRE(test_matrix(0, 0, 1) == 7);
    REQUIRE(test_matrix(0, 0, 2) == 13);
    REQUIRE(test_matrix(0, 0, 3) == 19);
    REQUIRE(test_matrix(0, 1, 0) == 3);
    REQUIRE(test_matrix(0, 1, 1) == 9);
    REQUIRE(test_matrix(0, 1, 2) == 15);
    REQUIRE(test_matrix(0, 1, 3) == 21);
    REQUIRE(test_matrix(0, 2, 0) == 5);
    REQUIRE(test_matrix(0, 2, 1) == 11);
    REQUIRE(test_matrix(0, 2, 2) == 17);
    REQUIRE(test_matrix(0, 2, 3) == 23);
    REQUIRE(test_matrix(1, 0, 0) == 2);
    REQUIRE(test_matrix(1, 0, 1) == 8);
    REQUIRE(test_matrix(1, 0, 2) == 14);
    REQUIRE(test_matrix(1, 0, 3) == 20);
    REQUIRE(test_matrix(1, 1, 0) == 4);
    REQUIRE(test_matrix(1, 1, 1) == 10);
    REQUIRE(test_matrix(1, 1, 2) == 16);
    REQUIRE(test_matrix(1, 1, 3) == 22);
    REQUIRE(test_matrix(1, 2, 0) == 6);
    REQUIRE(test_matrix(1, 2, 1) == 12);
    REQUIRE(test_matrix(1, 2, 2) == 18);
    REQUIRE(test_matrix(1, 2, 3) == 24);
}

TEMPLATE_TEST_CASE_2( "column_major/transpose/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 2, 3> a(etl::sequence_generator(1));

    REQUIRE(a(0, 0) == 1);
    REQUIRE(a(0, 1) == 3);
    REQUIRE(a(0, 2) == 5);
    REQUIRE(a(1, 0) == 2);
    REQUIRE(a(1, 1) == 4);
    REQUIRE(a(1, 2) == 6);

    etl::fast_matrix_cm<Z, 3, 2> b(etl::transpose(a));

    REQUIRE(b(0, 0) == 1);
    REQUIRE(b(1, 0) == 3);
    REQUIRE(b(2, 0) == 5);
    REQUIRE(b(0, 1) == 2);
    REQUIRE(b(1, 1) == 4);
    REQUIRE(b(2, 1) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/tranpose/2", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 3, 2> a(etl::sequence_generator(1));

    REQUIRE(a(0, 0) == 1);
    REQUIRE(a(0, 1) == 4);
    REQUIRE(a(1, 0) == 2);
    REQUIRE(a(1, 1) == 5);
    REQUIRE(a(2, 0) == 3);
    REQUIRE(a(2, 1) == 6);

    etl::fast_matrix_cm<Z, 2, 3> b(etl::transpose(a));

    REQUIRE(b(0, 0) == 1);
    REQUIRE(b(0, 1) == 2);
    REQUIRE(b(0, 2) == 3);
    REQUIRE(b(1, 0) == 4);
    REQUIRE(b(1, 1) == 5);
    REQUIRE(b(1, 2) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/binary/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 3, 2> a(etl::sequence_generator(1));
    etl::fast_matrix_cm<Z, 3, 2> b(a + a - a + a);

    REQUIRE(b(0, 0) == 2);
    REQUIRE(b(0, 1) == 8);
    REQUIRE(b(1, 0) == 4);
    REQUIRE(b(1, 1) == 10);
    REQUIRE(b(2, 0) == 6);
    REQUIRE(b(2, 1) == 12);
}
<commit_msg>new test<commit_after>//=======================================================================
// Copyright (c) 2014-2015 Baptiste Wicht // Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include <cmath>

#include "catch.hpp"
#include "template_test.hpp"

#include "etl/etl.hpp"

TEMPLATE_TEST_CASE_2( "column_major/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 2, 3> test_matrix(0);

    REQUIRE(test_matrix.size() == 6);

    REQUIRE(test_matrix.template dim<0>() == 2);
    REQUIRE(test_matrix.template dim<1>() == 3);
    REQUIRE(test_matrix.dim(0) == 2);
    REQUIRE(test_matrix.dim(1) == 3);

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0) == 1);
    REQUIRE(test_matrix(0, 1) == 3);
    REQUIRE(test_matrix(0, 2) == 5);
    REQUIRE(test_matrix(1, 0) == 2);
    REQUIRE(test_matrix(1, 1) == 4);
    REQUIRE(test_matrix(1, 2) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/2", "[dyn][cm]", Z, int, long ) {
    etl::dyn_matrix_cm<Z> test_matrix(2, 3);

    test_matrix = 0;

    REQUIRE(test_matrix.size() == 6);

    REQUIRE(test_matrix.template dim<0>() == 2);
    REQUIRE(test_matrix.template dim<1>() == 3);
    REQUIRE(test_matrix.dim(0) == 2);
    REQUIRE(test_matrix.dim(1) == 3);

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0) == 1);
    REQUIRE(test_matrix(0, 1) == 3);
    REQUIRE(test_matrix(0, 2) == 5);
    REQUIRE(test_matrix(1, 0) == 2);
    REQUIRE(test_matrix(1, 1) == 4);
    REQUIRE(test_matrix(1, 2) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/3", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 2, 3, 4> test_matrix;

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0, 0) == 1);
    REQUIRE(test_matrix(0, 0, 1) == 7);
    REQUIRE(test_matrix(0, 0, 2) == 13);
    REQUIRE(test_matrix(0, 0, 3) == 19);
    REQUIRE(test_matrix(0, 1, 0) == 3);
    REQUIRE(test_matrix(0, 1, 1) == 9);
    REQUIRE(test_matrix(0, 1, 2) == 15);
    REQUIRE(test_matrix(0, 1, 3) == 21);
    REQUIRE(test_matrix(0, 2, 0) == 5);
    REQUIRE(test_matrix(0, 2, 1) == 11);
    REQUIRE(test_matrix(0, 2, 2) == 17);
    REQUIRE(test_matrix(0, 2, 3) == 23);
    REQUIRE(test_matrix(1, 0, 0) == 2);
    REQUIRE(test_matrix(1, 0, 1) == 8);
    REQUIRE(test_matrix(1, 0, 2) == 14);
    REQUIRE(test_matrix(1, 0, 3) == 20);
    REQUIRE(test_matrix(1, 1, 0) == 4);
    REQUIRE(test_matrix(1, 1, 1) == 10);
    REQUIRE(test_matrix(1, 1, 2) == 16);
    REQUIRE(test_matrix(1, 1, 3) == 22);
    REQUIRE(test_matrix(1, 2, 0) == 6);
    REQUIRE(test_matrix(1, 2, 1) == 12);
    REQUIRE(test_matrix(1, 2, 2) == 18);
    REQUIRE(test_matrix(1, 2, 3) == 24);
}

TEMPLATE_TEST_CASE_2( "column_major/4", "[dyn][cm]", Z, int, long ) {
    etl::dyn_matrix_cm<Z, 3> test_matrix(2, 3, 4);

    for(std::size_t i = 0; i < test_matrix.size(); ++i){
        test_matrix[i] = i+1;
    }

    REQUIRE(test_matrix(0, 0, 0) == 1);
    REQUIRE(test_matrix(0, 0, 1) == 7);
    REQUIRE(test_matrix(0, 0, 2) == 13);
    REQUIRE(test_matrix(0, 0, 3) == 19);
    REQUIRE(test_matrix(0, 1, 0) == 3);
    REQUIRE(test_matrix(0, 1, 1) == 9);
    REQUIRE(test_matrix(0, 1, 2) == 15);
    REQUIRE(test_matrix(0, 1, 3) == 21);
    REQUIRE(test_matrix(0, 2, 0) == 5);
    REQUIRE(test_matrix(0, 2, 1) == 11);
    REQUIRE(test_matrix(0, 2, 2) == 17);
    REQUIRE(test_matrix(0, 2, 3) == 23);
    REQUIRE(test_matrix(1, 0, 0) == 2);
    REQUIRE(test_matrix(1, 0, 1) == 8);
    REQUIRE(test_matrix(1, 0, 2) == 14);
    REQUIRE(test_matrix(1, 0, 3) == 20);
    REQUIRE(test_matrix(1, 1, 0) == 4);
    REQUIRE(test_matrix(1, 1, 1) == 10);
    REQUIRE(test_matrix(1, 1, 2) == 16);
    REQUIRE(test_matrix(1, 1, 3) == 22);
    REQUIRE(test_matrix(1, 2, 0) == 6);
    REQUIRE(test_matrix(1, 2, 1) == 12);
    REQUIRE(test_matrix(1, 2, 2) == 18);
    REQUIRE(test_matrix(1, 2, 3) == 24);
}

TEMPLATE_TEST_CASE_2( "column_major/transpose/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 2, 3> a(etl::sequence_generator(1));

    REQUIRE(a(0, 0) == 1);
    REQUIRE(a(0, 1) == 3);
    REQUIRE(a(0, 2) == 5);
    REQUIRE(a(1, 0) == 2);
    REQUIRE(a(1, 1) == 4);
    REQUIRE(a(1, 2) == 6);

    etl::fast_matrix_cm<Z, 3, 2> b(etl::transpose(a));

    REQUIRE(b(0, 0) == 1);
    REQUIRE(b(1, 0) == 3);
    REQUIRE(b(2, 0) == 5);
    REQUIRE(b(0, 1) == 2);
    REQUIRE(b(1, 1) == 4);
    REQUIRE(b(2, 1) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/tranpose/2", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 3, 2> a(etl::sequence_generator(1));

    REQUIRE(a(0, 0) == 1);
    REQUIRE(a(0, 1) == 4);
    REQUIRE(a(1, 0) == 2);
    REQUIRE(a(1, 1) == 5);
    REQUIRE(a(2, 0) == 3);
    REQUIRE(a(2, 1) == 6);

    etl::fast_matrix_cm<Z, 2, 3> b(etl::transpose(a));

    REQUIRE(b(0, 0) == 1);
    REQUIRE(b(0, 1) == 2);
    REQUIRE(b(0, 2) == 3);
    REQUIRE(b(1, 0) == 4);
    REQUIRE(b(1, 1) == 5);
    REQUIRE(b(1, 2) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/binary/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 3, 2> a(etl::sequence_generator(1));
    etl::fast_matrix_cm<Z, 3, 2> b(a + a - a + a);

    REQUIRE(a(0, 0) == 1);
    REQUIRE(a(0, 1) == 4);
    REQUIRE(a(1, 0) == 2);
    REQUIRE(a(1, 1) == 5);
    REQUIRE(a(2, 0) == 3);
    REQUIRE(a(2, 1) == 6);
}

TEMPLATE_TEST_CASE_2( "column_major/sub/1", "[fast][cm]", Z, int, long ) {
    etl::fast_matrix_cm<Z, 3, 3, 2> a;
    etl::fast_matrix_cm<Z, 3, 2> b(a(1));

    a(0) = etl::sequence_generator(1);
    a(1) = etl::sequence_generator(7);
    a(2) = etl::sequence_generator(13);

    REQUIRE(a(0)(0, 0) == 1);
    REQUIRE(a(0)(0, 1) == 4);
    REQUIRE(a(0)(1, 0) == 2);
    REQUIRE(a(0)(1, 1) == 5);
    REQUIRE(a(0)(2, 0) == 3);
    REQUIRE(a(0)(2, 1) == 6);

    REQUIRE(b(0, 0) == 7);
    REQUIRE(b(0, 1) == 10);
    REQUIRE(b(1, 0) == 8);
    REQUIRE(b(1, 1) == 11);
    REQUIRE(b(2, 0) == 9);
    REQUIRE(b(2, 1) == 15);
}
<|endoftext|>