<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSerialPortInfo>
#include <QSerialPort>
#include "../arduino_st/simple_comm.h"
#include <thread>
#include <chrono>
#include "union_cast.h"
#include <QDebug>
#include <QTcpServer>
#include <QTcpSocket>
#include "stell_msg.h"
#include "star_math.h"
#include <QDir>
#include <QFileDialog>
#include <QtSql/QtSql>

//if defined - writes all Z-readings to the file (for debug purposes)
//#define EXPORT_Z

#define SQL_DRIVER "QSQLITE"

#ifdef EXPORT_Z
#include <QFile>

#ifndef NO_STELLARIUM_RUN
#define NO_STELLARIUM_RUN
#endif

#endif

Q_DECLARE_METATYPE(QSerialPortInfo);

static const QString nightScheme = "QWidget {background-color: #660000;}";

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    comThread(nullptr),
    skipWrite(ATOMIC_FLAG_INIT),
    gaz(0), gel(0),
    server(nullptr),
    readyToTrackMap(false)
{
    ui->setupUi(this);
    setWindowFlags( (windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);

    ui->latBox->setPrefixType(AngleSpinBox::PrefixType::Latitude);
    ui->lonBox->setPrefixType(AngleSpinBox::PrefixType::Longitude);

    database = QSqlDatabase::addDatabase(SQL_DRIVER, "DB");

    connect(this, &MainWindow::onArduinoRead, this, &MainWindow::arduinoRead, Qt::QueuedConnection);

    server = std::make_shared<QTcpServer>(nullptr);
    connect(server.get(), &QTcpServer::newConnection, this, [this]()
    {
        static uint64_t connCounter = 0;
        auto dumb = connCounter++;
        QPointer<QTcpSocket> tmp = stellarium[dumb] = server->nextPendingConnection();
        connect(tmp, &QAbstractSocket::disconnected, this, [this, dumb, tmp]()
        {
            if (stellarium.count(dumb))
                stellarium.erase(dumb);

            if (tmp)
                tmp->deleteLater();
        }, Qt::QueuedConnection);

        connect(tmp, &QTcpSocket::readyRead, this, [this, tmp]()
        {
            if (tmp)
                onStellariumDataReady(tmp);
        }, Qt::QueuedConnection);

    }, Qt::QueuedConnection);
    server->listen(QHostAddress::Any, 10001);

    on_pushButton_clicked();
    readSettings(this);
}

MainWindow::~MainWindow()
{
    comThread.reset();
    writeSettings(this);
    if (database.isOpen())
        database.close();
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
        case QEvent::LanguageChange:
            ui->retranslateUi(this);
            break;
        default:
            break;
    }
}

void MainWindow::recurseRead(QSettings &settings, QObject *object)
{
    Q_UNUSED(object);
    auto ps = settings.value("COMPort", "").toString();
    ui->cbPorts->setCurrentText(ps);
    ui->lonBox->setRadians(settings.value("Longitude", 0).toDouble());
    ui->latBox->setRadians(settings.value("Latitude", 0).toDouble());
    ui->cbNight->setChecked(settings.value("Night", false).toBool());
    ui->cbUseDb->setChecked(settings.value("UseDb", true).toBool());
    ui->editFolder->setText(settings.value("Folder", QDir::homePath()).toString());
}

void MainWindow::recurseWrite(QSettings &settings, QObject *object)
{
    Q_UNUSED(object);
    auto ps  = ui->cbPorts->currentText();
    settings.setValue("COMPort", ps);
    settings.setValue("Longitude", ui->lonBox->valueRadians());
    settings.setValue("Latitude",  ui->latBox->valueRadians());
    settings.setValue("Night", ui->cbNight->isChecked());
    settings.setValue("UseDb", ui->cbUseDb->isChecked());
    settings.setValue("Folder", ui->editFolder->text());
}

void MainWindow::on_pushButton_clicked()
{
    readyToTrackMap = false;
    comThread.reset();
    ui->cbPorts->clear();
    ui->cbPorts->addItem("Select to Stop");
    ui->cbPorts->blockSignals(true);
    auto pl = QSerialPortInfo::availablePorts();
    for (const auto& p : pl)
        ui->cbPorts->addItem(p.portName(), QVariant::fromValue<QSerialPortInfo>(p));
    ui->cbPorts->setCurrentIndex(0);
    ui->cbPorts->blockSignals(false);
}

void MainWindow::on_cbPorts_currentIndexChanged(int index)
{
    if (index > 0)
        startComPoll();
    else
        comThread.reset();
}

void MainWindow::startComPoll()
{
    comThread = utility::startNewRunner([this](auto stop)
    {
        using namespace std::chrono_literals;
        using namespace ard_st;

#ifdef EXPORT_Z
        QFile of (QDir::homePath()+"/sensor_values.csv");
        long os_counter = 0;
        of.open(QFile::WriteOnly | QFile::Truncate | QFile::Text);
        of.write("Azimuth, Altitude, W, X, Y, Z, Sample\n");
#endif

        while (!(*stop)) //device reconnect loop
        {
            QSerialPort port(ui->cbPorts->currentData().value<QSerialPortInfo>());
            port.setBaudRate(115200);
            //8N1 default settings
            port.setDataBits(QSerialPort::Data8);
            port.setParity(QSerialPort::Parity::NoParity);
            port.setStopBits(QSerialPort::OneStop);

            const bool op = port.open(QIODevice::ReadWrite);
            std::this_thread::sleep_for(15s); // device gets reset, have to wait
            port.setDataTerminalReady(false); //disable autoreset of device
            skipWrite.test_and_set();
            readyToTrackMap = false;
            uint64_t counter = 0;
            while (!(*stop))
            {
                if (op) //if failed to open, still should start thread which does nothing
                {
                    const static std::string header(MESSAGE_HDR);
                    Message msg;
                    packAzEl(msg.message.value, gaz, gel);
                    bool shouldSet = !skipWrite.test_and_set();

                    if (shouldSet)
                    {
                        //cleansing all sensor data there and let'em gather some
                        msg.message.Command = 'C';
                        port.write(header.c_str(), static_cast<int>(header.size()));
                        port.write(msg.buffer, sizeof(msg.buffer));
                        if (*stop || !port.waitForBytesWritten(5000))
                            break;
                        std::this_thread::sleep_for(500ms);
                    }

                    msg.message.Command = (shouldSet)?'S':'R';
                    port.write(header.c_str(), static_cast<int>(header.size()));
                    port.write(msg.buffer, sizeof(msg.buffer));

                    if (*stop || !port.waitForBytesWritten(5000))
                        break;

                    readyToTrackMap = readyToTrackMap || shouldSet;
                    if (!shouldSet)
                    {
                        const static auto msz = static_cast<decltype (port.bytesAvailable())>(sizeof(msg.message.value));
                        for(int i = 0; i < 100 && !(*stop) && port.bytesAvailable() < msz; ++i)
                            std::this_thread::sleep_for(20ms);

                        if (sizeof(msg.message.value.buffer) == port.read(msg.message.value.buffer, sizeof(msg.message.value.buffer)))
                        {
                            float az, el;
                            readAzEl(msg.message.value, &az, &el);
                            //qDebug() <<"Az = " <<degrees(az) << ";  El = "<<degrees(el);

                            emit this->onArduinoRead(az, el);
#ifdef EXPORT_Z

                            const static double div = 1 << (8 * sizeof(msg.message.value.vals.current_quat[0]) - 1);
                            of.write(QString("%1,%2,%3,%4,%5,%6,%7\n")
                                     .arg(degrees(az))
                                     .arg(degrees(el))
                                     .arg(msg.message.value.vals.current_quat[0] / div)
                                    .arg(msg.message.value.vals.current_quat[1] / div)
                                    .arg(msg.message.value.vals.current_quat[2] / div)
                                    .arg(msg.message.value.vals.current_quat[3] / div)
                                    .arg(os_counter++).toUtf8());
#endif
                        }
                    }
                    else
                        ++counter;
                }
                else
                    break;
                std::this_thread::sleep_for(500ms);
            }
            if (!(*stop))
                std::this_thread::sleep_for(5000ms);
        }
    });
}

void MainWindow::writeToArduino(float az_rad, float el_rad)
{
    gaz = az_rad;
    gel = el_rad;
    skipWrite.clear();
}

int64_t MainWindow::getMicrosNow()
{
    using namespace std::chrono;
    return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
}

void MainWindow::arduinoRead(float az_rad, float el_rad)
{
    ui->lblAz-> setText(QString("%1").arg(degrees(az_rad)));
    ui->lblAlt->setText(QString("%1").arg(degrees(el_rad)));
    if (readyToTrackMap && stellarium.size())
    {
        //writting alt/az from arduino to stellarium
        double ra, dec;
        convertAZ_RA(static_cast<double>(az_rad), static_cast<double>(el_rad), ui->latBox->valueRadians(), ui->lonBox->valueRadians(), ra, dec);
        //qDebug() << "Az(deg): "<< degrees(az_rad)<<" ALT(deg): "<<degrees(el_rad);
        //qDebug() << "RA(hrs): "<< degrees(ra) / 15 << " DEC(deg): "<< degrees(dec);
        if (stellarium.size())
        {

            ToStellMessage msg;
            msg.msg.size = sizeof(ToStellMessage);
            msg.msg.type   = 0;
            msg.msg.status = 0;
            msg.msg.clientMicros = getMicrosNow();
            //from ServerDummy.cpp
            msg.msg.ra_int  = static_cast<decltype(msg.msg.ra_int)>(floor(0.5   +  ra * static_cast<uint64_t>(0x80000000)/M_PI));
            msg.msg.dec_int = static_cast<decltype(msg.msg.dec_int)>(floor(0.5 +  dec * static_cast<uint64_t>(0x80000000)/M_PI)); //yes, uint64_t or u get negated dec
            for (const auto & s : stellarium)
            {

                s.second->write(msg.buffer, sizeof(ToStellMessage));
            }
            if (ui->cbUseDb->isChecked())
            {
                if (!database.isOpen())
                {
                    const static QString datestr = QDate::currentDate().toString("dd_MMM_yyyy");
                    QString sqlDb = ui->editFolder->text() + QDir::separator() + datestr + "_startrack.db";

                    database.setDatabaseName(sqlDb);
                    if (database.open())
                    {
                        //ensruing it has all needed tables
                        QSqlQuery sql(database);
                        qDebug() <<"CREATE TABLE: " <<
                                   sql.exec("CREATE TABLE IF NOT EXISTS Track(ID integer primary key asc, "
                                            "Az_rad REAL not null, Alt_rad REAL not null, LocalDt INTEGER not null, W INTEGER, X INTEGER, Y INTEGER, Z INTEGER);"
                                            );
                        qDebug() <<"CREATE INDEX: " <<
                                   sql.exec("CREATE UNIQUE INDEX IF NOT EXISTS Track_LocalDt ON Track(LocalDt);");
                    }
                }

                if (database.isOpen())
                {
                    QSqlQuery sql(database);
                    sql.exec(QString("INSERT OR REPLACE INTO Track(Az_rad, Alt_rad, LocalDt) VALUES(%1, %2, %3)")
                             .arg(az_rad).arg(el_rad).arg(QDateTime::currentMSecsSinceEpoch()));
                }
            }
        }
    }
}

void MainWindow::onStellariumDataReady(QTcpSocket *p)
{
    auto all = p->readAll();
    u_int16_t size = *reinterpret_cast<uint16_t*>(all.data()); //size counts itself, but we dont place it in packet
    //qDebug() << "Packet Size: "<<size;
    if (!(size < 4 || size > all.size() || size - 2 > sizeof(StellBasicMessage)))
    {
        StellBasicMessage msg;
        memcpy(msg.buffer, all.data() + 2, size - 2);
        //qDebug() << msg.msg.clientMicros << msg.msg.ra_int << msg.msg.dec_int;

        //took from ServerDummy.cpp, it is RADIANS now as we want
        const double ra  = msg.msg.ra_int  * (M_PI/static_cast<uint64_t>(0x80000000));
        const double dec = msg.msg.dec_int * (M_PI/static_cast<uint64_t>(0x80000000));
        // qDebug() << "RA(hrs): "<< degrees(ra) / 15 << " DEC(deg): "<< degrees(dec);
        double az, alt;
        convertRA_AZ(ra, dec, ui->latBox->valueRadians(), ui->lonBox->valueRadians(), az, alt);
        //qDebug() << "Az(deg): "<< degrees(az)<<" ALT(deg): "<<degrees(alt);
        writeToArduino(static_cast<float>(az), static_cast<float>(alt));
    }
}

void MainWindow::on_cbNight_toggled(bool checked)
{
    if (checked)
        qApp->setStyleSheet(nightScheme);
    else
        qApp->setStyleSheet("");
}

void MainWindow::on_btnSelectFodler_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("Select folderto save tracks"), ui->editFolder->text(),
                                                    QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!dir.isEmpty())
    {
        ui->editFolder->setText(dir);
        if (database.isOpen())
            database.close();
    }
}
<commit_msg>added to DB ra/dec, that should be better<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSerialPortInfo>
#include <QSerialPort>
#include "../arduino_st/simple_comm.h"
#include <thread>
#include <chrono>
#include "union_cast.h"
#include <QDebug>
#include <QTcpServer>
#include <QTcpSocket>
#include "stell_msg.h"
#include "star_math.h"
#include <QDir>
#include <QFileDialog>
#include <QtSql/QtSql>

//if defined - writes all Z-readings to the file (for debug purposes)
//#define EXPORT_Z

#define SQL_DRIVER "QSQLITE"

#ifdef EXPORT_Z
#include <QFile>

#ifndef NO_STELLARIUM_RUN
#define NO_STELLARIUM_RUN
#endif

#endif

Q_DECLARE_METATYPE(QSerialPortInfo);

static const QString nightScheme = "QWidget {background-color: #660000;}";

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    comThread(nullptr),
    skipWrite(ATOMIC_FLAG_INIT),
    gaz(0), gel(0),
    server(nullptr),
    readyToTrackMap(false)
{
    ui->setupUi(this);
    setWindowFlags( (windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);

    ui->latBox->setPrefixType(AngleSpinBox::PrefixType::Latitude);
    ui->lonBox->setPrefixType(AngleSpinBox::PrefixType::Longitude);

    database = QSqlDatabase::addDatabase(SQL_DRIVER, "DB");

    connect(this, &MainWindow::onArduinoRead, this, &MainWindow::arduinoRead, Qt::QueuedConnection);

    server = std::make_shared<QTcpServer>(nullptr);
    connect(server.get(), &QTcpServer::newConnection, this, [this]()
    {
        static uint64_t connCounter = 0;
        auto dumb = connCounter++;
        QPointer<QTcpSocket> tmp = stellarium[dumb] = server->nextPendingConnection();
        connect(tmp, &QAbstractSocket::disconnected, this, [this, dumb, tmp]()
        {
            if (stellarium.count(dumb))
                stellarium.erase(dumb);

            if (tmp)
                tmp->deleteLater();
        }, Qt::QueuedConnection);

        connect(tmp, &QTcpSocket::readyRead, this, [this, tmp]()
        {
            if (tmp)
                onStellariumDataReady(tmp);
        }, Qt::QueuedConnection);

    }, Qt::QueuedConnection);
    server->listen(QHostAddress::Any, 10001);

    on_pushButton_clicked();
    readSettings(this);
}

MainWindow::~MainWindow()
{
    comThread.reset();
    writeSettings(this);
    if (database.isOpen())
        database.close();
    delete ui;
}

void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
        case QEvent::LanguageChange:
            ui->retranslateUi(this);
            break;
        default:
            break;
    }
}

void MainWindow::recurseRead(QSettings &settings, QObject *object)
{
    Q_UNUSED(object);
    auto ps = settings.value("COMPort", "").toString();
    ui->cbPorts->setCurrentText(ps);
    ui->lonBox->setRadians(settings.value("Longitude", 0).toDouble());
    ui->latBox->setRadians(settings.value("Latitude", 0).toDouble());
    ui->cbNight->setChecked(settings.value("Night", false).toBool());
    ui->cbUseDb->setChecked(settings.value("UseDb", true).toBool());
    ui->editFolder->setText(settings.value("Folder", QDir::homePath()).toString());
}

void MainWindow::recurseWrite(QSettings &settings, QObject *object)
{
    Q_UNUSED(object);
    auto ps  = ui->cbPorts->currentText();
    settings.setValue("COMPort", ps);
    settings.setValue("Longitude", ui->lonBox->valueRadians());
    settings.setValue("Latitude",  ui->latBox->valueRadians());
    settings.setValue("Night", ui->cbNight->isChecked());
    settings.setValue("UseDb", ui->cbUseDb->isChecked());
    settings.setValue("Folder", ui->editFolder->text());
}

void MainWindow::on_pushButton_clicked()
{
    readyToTrackMap = false;
    comThread.reset();
    ui->cbPorts->clear();
    ui->cbPorts->addItem("Select to Stop");
    ui->cbPorts->blockSignals(true);
    auto pl = QSerialPortInfo::availablePorts();
    for (const auto& p : pl)
        ui->cbPorts->addItem(p.portName(), QVariant::fromValue<QSerialPortInfo>(p));
    ui->cbPorts->setCurrentIndex(0);
    ui->cbPorts->blockSignals(false);
}

void MainWindow::on_cbPorts_currentIndexChanged(int index)
{
    if (index > 0)
        startComPoll();
    else
        comThread.reset();
}

void MainWindow::startComPoll()
{
    comThread = utility::startNewRunner([this](auto stop)
    {
        using namespace std::chrono_literals;
        using namespace ard_st;

#ifdef EXPORT_Z
        QFile of (QDir::homePath()+"/sensor_values.csv");
        long os_counter = 0;
        of.open(QFile::WriteOnly | QFile::Truncate | QFile::Text);
        of.write("Azimuth, Altitude, W, X, Y, Z, Sample\n");
#endif

        while (!(*stop)) //device reconnect loop
        {
            QSerialPort port(ui->cbPorts->currentData().value<QSerialPortInfo>());
            port.setBaudRate(115200);
            //8N1 default settings
            port.setDataBits(QSerialPort::Data8);
            port.setParity(QSerialPort::Parity::NoParity);
            port.setStopBits(QSerialPort::OneStop);

            const bool op = port.open(QIODevice::ReadWrite);
            std::this_thread::sleep_for(15s); // device gets reset, have to wait
            port.setDataTerminalReady(false); //disable autoreset of device
            skipWrite.test_and_set();
            readyToTrackMap = false;
            uint64_t counter = 0;
            while (!(*stop))
            {
                if (op) //if failed to open, still should start thread which does nothing
                {
                    const static std::string header(MESSAGE_HDR);
                    Message msg;
                    packAzEl(msg.message.value, gaz, gel);
                    bool shouldSet = !skipWrite.test_and_set();

                    if (shouldSet)
                    {
                        //cleansing all sensor data there and let'em gather some
                        msg.message.Command = 'C';
                        port.write(header.c_str(), static_cast<int>(header.size()));
                        port.write(msg.buffer, sizeof(msg.buffer));
                        if (*stop || !port.waitForBytesWritten(5000))
                            break;
                        std::this_thread::sleep_for(500ms);
                    }

                    msg.message.Command = (shouldSet)?'S':'R';
                    port.write(header.c_str(), static_cast<int>(header.size()));
                    port.write(msg.buffer, sizeof(msg.buffer));

                    if (*stop || !port.waitForBytesWritten(5000))
                        break;

                    readyToTrackMap = readyToTrackMap || shouldSet;
                    if (!shouldSet)
                    {
                        const static auto msz = static_cast<decltype (port.bytesAvailable())>(sizeof(msg.message.value));
                        for(int i = 0; i < 100 && !(*stop) && port.bytesAvailable() < msz; ++i)
                            std::this_thread::sleep_for(20ms);

                        if (sizeof(msg.message.value.buffer) == port.read(msg.message.value.buffer, sizeof(msg.message.value.buffer)))
                        {
                            float az, el;
                            readAzEl(msg.message.value, &az, &el);
                            //qDebug() <<"Az = " <<degrees(az) << ";  El = "<<degrees(el);

                            emit this->onArduinoRead(az, el);
#ifdef EXPORT_Z

                            const static double div = 1 << (8 * sizeof(msg.message.value.vals.current_quat[0]) - 1);
                            of.write(QString("%1,%2,%3,%4,%5,%6,%7\n")
                                     .arg(degrees(az))
                                     .arg(degrees(el))
                                     .arg(msg.message.value.vals.current_quat[0] / div)
                                    .arg(msg.message.value.vals.current_quat[1] / div)
                                    .arg(msg.message.value.vals.current_quat[2] / div)
                                    .arg(msg.message.value.vals.current_quat[3] / div)
                                    .arg(os_counter++).toUtf8());
#endif
                        }
                    }
                    else
                        ++counter;
                }
                else
                    break;
                std::this_thread::sleep_for(500ms);
            }
            if (!(*stop))
                std::this_thread::sleep_for(5000ms);
        }
    });
}

void MainWindow::writeToArduino(float az_rad, float el_rad)
{
    gaz = az_rad;
    gel = el_rad;
    skipWrite.clear();
}

int64_t MainWindow::getMicrosNow()
{
    using namespace std::chrono;
    return duration_cast<microseconds>(system_clock::now().time_since_epoch()).count();
}

void MainWindow::arduinoRead(float az_rad, float el_rad)
{
    ui->lblAz-> setText(QString("%1").arg(degrees(az_rad)));
    ui->lblAlt->setText(QString("%1").arg(degrees(el_rad)));
    if (readyToTrackMap && stellarium.size())
    {
        //writting alt/az from arduino to stellarium
        double ra, dec;
        convertAZ_RA(static_cast<double>(az_rad), static_cast<double>(el_rad), ui->latBox->valueRadians(), ui->lonBox->valueRadians(), ra, dec);
        //qDebug() << "Az(deg): "<< degrees(az_rad)<<" ALT(deg): "<<degrees(el_rad);
        //qDebug() << "RA(hrs): "<< degrees(ra) / 15 << " DEC(deg): "<< degrees(dec);
        if (stellarium.size())
        {

            ToStellMessage msg;
            msg.msg.size = sizeof(ToStellMessage);
            msg.msg.type   = 0;
            msg.msg.status = 0;
            msg.msg.clientMicros = getMicrosNow();
            //from ServerDummy.cpp
            msg.msg.ra_int  = static_cast<decltype(msg.msg.ra_int)>(floor(0.5   +  ra * static_cast<uint64_t>(0x80000000)/M_PI));
            msg.msg.dec_int = static_cast<decltype(msg.msg.dec_int)>(floor(0.5 +  dec * static_cast<uint64_t>(0x80000000)/M_PI)); //yes, uint64_t or u get negated dec
            for (const auto & s : stellarium)
            {

                s.second->write(msg.buffer, sizeof(ToStellMessage));
            }
            if (ui->cbUseDb->isChecked())
            {
                if (!database.isOpen())
                {
                    const static QString datestr = QDate::currentDate().toString("dd_MMM_yyyy");
                    QString sqlDb = ui->editFolder->text() + QDir::separator() + datestr + "_startrack.db";

                    database.setDatabaseName(sqlDb);
                    if (database.open())
                    {
                        //ensruing it has all needed tables
                        QSqlQuery sql(database);
                        qDebug() <<"CREATE TABLE: " <<
                                   sql.exec("CREATE TABLE IF NOT EXISTS Track(ID integer primary key asc, "
                                            "Az_rad REAL not null, Alt_rad REAL not null, LocalDt INTEGER not null, RA_rad not null, DEC_rad not null, "
                                            "W INTEGER, X INTEGER, Y INTEGER, Z INTEGER);"
                                            );
                        qDebug() <<"CREATE INDEX: " <<
                                   sql.exec("CREATE UNIQUE INDEX IF NOT EXISTS Track_LocalDt ON Track(LocalDt);");
                    }
                }

                if (database.isOpen())
                {
                    QSqlQuery sql(database);
                    sql.exec(QString("INSERT OR REPLACE INTO Track(Az_rad, Alt_rad, RA_rad, DEC_rad, LocalDt) VALUES(%1, %2, %3)")
                             .arg(az_rad).arg(el_rad).arg(ra).arg(dec)
                             .arg(QDateTime::currentMSecsSinceEpoch()));
                }
            }
        }
    }
}

void MainWindow::onStellariumDataReady(QTcpSocket *p)
{
    auto all = p->readAll();
    u_int16_t size = *reinterpret_cast<uint16_t*>(all.data()); //size counts itself, but we dont place it in packet
    //qDebug() << "Packet Size: "<<size;
    if (!(size < 4 || size > all.size() || size - 2 > sizeof(StellBasicMessage)))
    {
        StellBasicMessage msg;
        memcpy(msg.buffer, all.data() + 2, size - 2);
        //qDebug() << msg.msg.clientMicros << msg.msg.ra_int << msg.msg.dec_int;

        //took from ServerDummy.cpp, it is RADIANS now as we want
        const double ra  = msg.msg.ra_int  * (M_PI/static_cast<uint64_t>(0x80000000));
        const double dec = msg.msg.dec_int * (M_PI/static_cast<uint64_t>(0x80000000));
        // qDebug() << "RA(hrs): "<< degrees(ra) / 15 << " DEC(deg): "<< degrees(dec);
        double az, alt;
        convertRA_AZ(ra, dec, ui->latBox->valueRadians(), ui->lonBox->valueRadians(), az, alt);
        //qDebug() << "Az(deg): "<< degrees(az)<<" ALT(deg): "<<degrees(alt);
        writeToArduino(static_cast<float>(az), static_cast<float>(alt));
    }
}

void MainWindow::on_cbNight_toggled(bool checked)
{
    if (checked)
        qApp->setStyleSheet(nightScheme);
    else
        qApp->setStyleSheet("");
}

void MainWindow::on_btnSelectFodler_clicked()
{
    QString dir = QFileDialog::getExistingDirectory(this, tr("Select folderto save tracks"), ui->editFolder->text(),
                                                    QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    if (!dir.isEmpty())
    {
        ui->editFolder->setText(dir);
        if (database.isOpen())
            database.close();
    }
}
<|endoftext|>


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

#ifndef PCL_POINT_CLOUD_SPRING_IMPL_HPP_
#define PCL_POINT_CLOUD_SPRING_IMPL_HPP_

template <typename PointT> inline bool
pcl::PointCloudSpring<PointT>::initCompute ()
{
  if ((expand_policy_ != MIRROR) && (expand_policy_ != DUPLICATE))
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "expansion policy is either MIRROR or DUPLICATE");
    return false;
  }

  if ((direction_ != HORIZONTAL) && (direction_ != VERTICAL) && (direction_ != BOTH))
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "border must be a HORIZONTAL, VERTICAL or BOTH");
    return false;
  }

  if (amount_ <= 0)
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "expansion amount must be strict positive!");
    return false;
  }

  if (!input_->isOrganized () && (expand_policy_ == VERTICAL || expand_policy_ == BOTH))
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "vertical expansion requires organised point cloud");
    return false;
  }
  return true;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandHorizontal(const PointT& val)
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  uint32_t new_width = old_width + 2*amount_;
  for (int j = 0; j < input_->height; ++j)
  {
    iterator start = input_->begin() + (j * new_width);
    input_->insert (start, amount_, val);
    start = input_->begin() + (j * new_width) + old_width + amount_;
    input_->insert (start, amount_, val);
    input_->height = old_height;
  }
  input_->width = old_width + 2*amount_;
  input_->height = old_height;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandVertical(const PointT& val)
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  input_->insert (input_->begin (), amount_ * old_width, val);
  iterator last = input_->end () -1;
  input_->insert (last, amount_ * old_width, val);
  input_->width = old_width;
  input_->height = old_height + 2*amount_;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandHorizontalDuplicate()
{
  int old_height = input_->height;
  int old_width = input_->width;
  int new_width = old_width + 2*amount_;
  for (int j = 0; j < old_height; ++j)
    for(int i = 0; i < amount_; ++i)
    {
      iterator start = input_->begin () + (j * new_width);
      input_->insert (start, *start);
      start = input_->begin () + (j * new_width) + old_width + i;
      input_->insert (start, *start);
    }

  input_->width = old_width + 2*amount_;
  input_->height = old_height;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandVerticalDuplicate()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  for(int i = 0; i < amount_; ++i)
  {
    input_->insert (input_->begin (), input_->begin (), input_->begin () + old_width);
    input_->insert (input_->end (), input_->end () - old_width, input_->end ());
  }
  input_->width = old_width;
  input_->height = old_height + 2*amount_;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandHorizontalMirror()
{
  int old_height = input_->height;
  int old_width = input_->width;
  int new_width = old_width + 2*amount_;
  for (int j = 0; j < old_height; ++j)
    for(int i = 0; i < amount_; ++i)
    {
      iterator start = input_->begin () + (j * new_width);
      input_->insert (start, *(start + 2*i));
      start = input_->begin () + (j * new_width) + old_width + 2*i;
      input_->insert (start+1, *(start - 2*i));
    }
  input_->width = old_width + 2*amount_;
  input_->height = old_height;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandVerticalMirror()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;

  iterator up = input_->begin (), low = input_->end ();
  for(int i = 0; i < amount_; ++i)
  {
    input_->insert (input_->begin (), up, up + old_width);
    up+= old_width;
    input_->insert (input_->end (), low - old_width, low);
    low-= old_width;
  }
  input_->width = old_width;
  input_->height = old_height + 2*amount_;
}

template <typename PointT> inline void
pcl::PointCloudSpring<PointT>::deleteRows ()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  input_->erase (input_->begin (), input_->begin () + amount_ * old_width);
  input_->erase (input_->end () - amount_ * old_width, input_->end ());
  input_->height = old_height - 2*amount_;
  input_->width = old_width;
}

template <typename PointT> inline void
pcl::PointCloudSpring<PointT>::deleteCols ()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  uint32_t new_width = old_width - 2 * amount_;
  for(uint32_t j = 0; j < old_height; j++)
  {
    iterator start = input_->begin () + j * new_width;
    input_->erase (start, start + amount_);
    start = input_->begin () + (j+1) * new_width;
    input_->erase (start, start + amount_);
  }
  input_->height = old_height;
  input_->width = new_width;
}

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

#ifndef PCL_POINT_CLOUD_SPRING_IMPL_HPP_
#define PCL_POINT_CLOUD_SPRING_IMPL_HPP_

template <typename PointT> inline bool
pcl::PointCloudSpring<PointT>::initCompute ()
{
  if ((expand_policy_ != MIRROR) && (expand_policy_ != DUPLICATE))
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "expansion policy is either MIRROR or DUPLICATE");
    return false;
  }

  if ((direction_ != HORIZONTAL) && (direction_ != VERTICAL) && (direction_ != BOTH))
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "border must be a HORIZONTAL, VERTICAL or BOTH");
    return false;
  }

  if (amount_ <= 0)
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "expansion amount must be strict positive!");
    return false;
  }

  if (!input_->isOrganized () && (expand_policy_ == VERTICAL || expand_policy_ == BOTH))
  {
    PCL_THROW_EXCEPTION (InitFailedException,
                         "[pcl::PointCloudSpring::initCompute] init failed: "
                         << "vertical expansion requires organised point cloud");
    return false;
  }
  return true;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandHorizontal(const PointT& val)
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  uint32_t new_width = old_width + 2*amount_;
  for (int j = 0; j < input_->height; ++j)
  {
    iterator start = input_->begin() + (j * new_width);
    input_->insert (start, amount_, val);
    start = input_->begin() + (j * new_width) + old_width + amount_;
    input_->insert (start, amount_, val);
    input_->height = old_height;
  }
  input_->width = old_width + 2*amount_;
  input_->height = old_height;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandVertical(const PointT& val)
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  input_->insert (input_->begin (), amount_ * old_width, val);
  iterator last = input_->end () -1;
  input_->insert (last, amount_ * old_width, val);
  input_->width = old_width;
  input_->height = old_height + 2*amount_;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandHorizontalDuplicate()
{
  int old_height = input_->height;
  int old_width = input_->width;
  int new_width = old_width + 2*amount_;
  for (int j = 0; j < old_height; ++j)
    for(int i = 0; i < amount_; ++i)
    {
      iterator start = input_->begin () + (j * new_width);
      input_->insert (start, *start);
      start = input_->begin () + (j * new_width) + old_width + i;
      input_->insert (start, *start);
    }

  input_->width = old_width + 2*amount_;
  input_->height = old_height;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandVerticalDuplicate()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  for(int i = 0; i < amount_; ++i)
  {
    input_->insert (input_->begin (), input_->begin (), input_->begin () + old_width);
    input_->insert (input_->end (), input_->end () - old_width, input_->end ());
  }
  input_->width = old_width;
  input_->height = old_height + 2*amount_;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandHorizontalMirror()
{
  int old_height = input_->height;
  int old_width = input_->width;
  int new_width = old_width + 2*amount_;
  for (int j = 0; j < old_height; ++j)
    for(int i = 0; i < amount_; ++i)
    {
      iterator start = input_->begin () + (j * new_width);
      input_->insert (start, *(start + 2*i));
      start = input_->begin () + (j * new_width) + old_width + 2*i;
      input_->insert (start+1, *(start - 2*i));
    }
  input_->width = old_width + 2*amount_;
  input_->height = old_height;
}

template <typename PointT> void
pcl::PointCloudSpring<PointT>::expandVerticalMirror()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;

  iterator up = input_->begin (), low = input_->end ();
  for(int i = 0; i < amount_; ++i)
  {
    up = input_->begin () + 2*i*old_width;
    input_->insert (input_->begin (), up, up + old_width);
    low = input_->end () - 2*i*old_width;
    input_->insert (input_->end (), low - old_width, low);
  }
  input_->width = old_width;
  input_->height = old_height + 2*amount_;
}

template <typename PointT> inline void
pcl::PointCloudSpring<PointT>::deleteRows ()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  input_->erase (input_->begin (), input_->begin () + amount_ * old_width);
  input_->erase (input_->end () - amount_ * old_width, input_->end ());
  input_->height = old_height - 2*amount_;
  input_->width = old_width;
}

template <typename PointT> inline void
pcl::PointCloudSpring<PointT>::deleteCols ()
{
  uint32_t old_height = input_->height;
  uint32_t old_width = input_->width;
  uint32_t new_width = old_width - 2 * amount_;
  for(uint32_t j = 0; j < old_height; j++)
  {
    iterator start = input_->begin () + j * new_width;
    input_->erase (start, start + amount_);
    start = input_->begin () + (j+1) * new_width;
    input_->erase (start, start + amount_);
  }
  input_->height = old_height;
  input_->width = new_width;
}

#endif
<|endoftext|>


<commit_before>/*
Copyright (c) 2011 Tim Howard

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 <stdio.h>
#include <string>
#include <duct/filestream.hpp>
#include "sdpk2.hpp"
#include "sdmd2.hpp"

using namespace PK2Unpack;

char __hash_str[33]={0x00};
const char* __hash_str_ptr=NULL;

void dump_entry(SDPK2& pak, const Entry& entry, const char* outdir, const char* outpath) {
	std::string path(outdir);
	path.append(outpath);
	printf("Dumping [%.*s] to %s\n", 32, __hash_str_ptr, path.c_str());
	FileStream* out=FileStream::writeFile(path.c_str());
	if (out) {
		if (entry.readToStream(pak.getStream(), out, pak)!=0) {
			printf("\tFailed to decompress/write some blocks\n");
		}
		out->close();
		delete out;
	} else {
		printf("\tFailed to open %s for writing\n", path.c_str());
	}
}

int main(int argc, char** argv) {
	if (argc<2) {
		printf("ERROR: sdpk2/sdmd2 path required\n");
		return 1;
	}
	const char* path=argv[1];
	size_t len=strlen(path);
	if (strncmp((path+len)-5, "sdmd2", 5)==0) {
		SDMD2 table(path);
		if (table.load()) {
			table.printInfo();
		} else {
			return 1;
		}
	} else if (strncmp((path+len)-5, "sdpk2", 5)==0) {
		SDPK2 pak(path);
		if (pak.open()) {
			//pak.printInfo(0, true);
			if (argc>2) {
				__hash_str_ptr=argv[2];
				if (argc>3) {
					path=argv[3];
				} else {
					path=argv[2];
				}
				MD5Hash hash;
				if (strncmp(__hash_str_ptr, "-a", 2)==0) {
					__hash_str_ptr=__hash_str;
					const EntryVec& entries=pak.getEntries();
					for (size_t i=0; i<entries.size(); ++i) {
						entries[i].hash().getExisting(__hash_str, false);
						dump_entry(pak, entries[i], "dump/", __hash_str_ptr);
					}
				} else if (hash.set(__hash_str_ptr)) {
					const Entry* entry=pak.findEntry(hash);
					if (entry) {
						dump_entry(pak, *entry, "dump/", path);
					} else {
						printf("Entry [%s] not found\n", __hash_str_ptr);
						return 1;
					}
				} else {
					printf("Malformed hash\n");
					return 1;
				}
			}
			pak.close();
		} else {
			return 1;
		}
	} else {
		printf("File extension not recognized\n");
	}
	return 0;
}

<commit_msg>Outputs to given path or to `dump/` with no given path.<commit_after>/*
Copyright (c) 2011 Tim Howard

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 <stdio.h>
#include <string>
#include <duct/filestream.hpp>
#include "sdpk2.hpp"
#include "sdmd2.hpp"

using namespace PK2Unpack;

char __hash_str[33]={0x00};
const char* __hash_str_ptr=NULL;

void dump_entry(SDPK2& pak, const Entry& entry, const char* outdir, const char* outpath) {
	std::string path(outdir);
	path.append(outpath);
	printf("Dumping [%.*s] to %s\n", 32, __hash_str_ptr, path.c_str());
	FileStream* out=FileStream::writeFile(path.c_str());
	if (out) {
		if (entry.readToStream(pak.getStream(), out, pak)!=0) {
			printf("\tFailed to decompress/write some blocks\n");
		}
		out->close();
		delete out;
	} else {
		printf("\tFailed to open %s for writing\n", path.c_str());
	}
}

int main(int argc, char** argv) {
	if (argc<2) {
		printf("ERROR: sdpk2/sdmd2 path required\n");
		return 1;
	}
	const char* path=argv[1];
	size_t len=strlen(path);
	if (strncmp((path+len)-5, "sdmd2", 5)==0) {
		SDMD2 table(path);
		if (table.load()) {
			table.printInfo();
		} else {
			return 1;
		}
	} else if (strncmp((path+len)-5, "sdpk2", 5)==0) {
		SDPK2 pak(path);
		if (pak.open()) {
			//pak.printInfo(0, true);
			if (argc>2) {
				__hash_str_ptr=argv[2];
				if (argc>3) {
					path=argv[3];
				} else {
					path=argv[2];
				}
				MD5Hash hash;
				if (strncmp(__hash_str_ptr, "-a", 2)==0) {
					__hash_str_ptr=__hash_str;
					if (strncmp(path, "-a", 2)==0) {
						path="dump/";
					}
					const EntryVec& entries=pak.getEntries();
					for (size_t i=0; i<entries.size(); ++i) {
						entries[i].hash().getExisting(__hash_str, false);
						dump_entry(pak, entries[i], path, __hash_str_ptr);
					}
				} else if (hash.set(__hash_str_ptr)) {
					const Entry* entry=pak.findEntry(hash);
					if (entry) {
						dump_entry(pak, *entry, "dump/", path);
					} else {
						printf("Entry [%s] not found\n", __hash_str_ptr);
						return 1;
					}
				} else {
					printf("Malformed hash\n");
					return 1;
				}
			}
			pak.close();
		} else {
			return 1;
		}
	} else {
		printf("File extension not recognized\n");
	}
	return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AUser.cxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 02:16:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#ifndef _CONNECTIVITY_ADO_USER_HXX_
#include "ado/AUser.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_CATALOG_HXX_
#include "ado/ACatalog.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_GROUPS_HXX_
#include "ado/AGroups.hxx"
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _CONNECTIVITY_ADO_BCONNECTION_HXX_
#include "ado/AConnection.hxx"
#endif

#ifndef _CONNECTIVITY_ADO_AWRAPADO_HXX_
#include "ado/Awrapado.hxx"
#endif

using namespace connectivity::ado;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;

// -------------------------------------------------------------------------
OAdoUser::OAdoUser(OCatalog* _pParent,sal_Bool _bCase, ADOUser* _pUser)
    : OUser_TYPEDEF(_bCase)
    ,m_pCatalog(_pParent)
{
    construct();

    if(_pUser)
        m_aUser = WpADOUser(_pUser);
    else
        m_aUser.Create();
}
// -------------------------------------------------------------------------
OAdoUser::OAdoUser(OCatalog* _pParent,sal_Bool _bCase,   const ::rtl::OUString& _Name)
    : OUser_TYPEDEF(_Name,_bCase)
    , m_pCatalog(_pParent)
{
    construct();
    m_aUser.Create();
    m_aUser.put_Name(_Name);
}
// -------------------------------------------------------------------------
void OAdoUser::refreshGroups()
{
    TStringVector aVector;
    WpADOGroups aGroups(m_aUser.get_Groups());
    aGroups.fillElementNames(aVector);
    if(m_pGroups)
        m_pGroups->reFill(aVector);
    else
        m_pGroups = new OGroups(m_pCatalog,m_aMutex,aVector,aGroups,isCaseSensitive());
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdoUser::getUnoTunnelImplementationId()
{
    static ::cppu::OImplementationId * pId = 0;
    if (! pId)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! pId)
        {
            static ::cppu::OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdoUser::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
                ? reinterpret_cast< sal_Int64 >( this )
                : OUser_TYPEDEF::getSomething(rId);
}

// -------------------------------------------------------------------------
void OAdoUser::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)throw (Exception)
{
    if(m_aUser.IsValid())
    {

        switch(nHandle)
        {
            case PROPERTY_ID_NAME:
                {
                    ::rtl::OUString aVal;
                    rValue >>= aVal;
                    m_aUser.put_Name(aVal);
                }
                break;
        }
    }
}
// -------------------------------------------------------------------------
void OAdoUser::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
{
    if(m_aUser.IsValid())
    {
        switch(nHandle)
        {
            case PROPERTY_ID_NAME:
                rValue <<= m_aUser.get_Name();
                break;
        }
    }
}
// -------------------------------------------------------------------------
OUserExtend::OUserExtend(OCatalog* _pParent,sal_Bool _bCase,    ADOUser* _pUser)
    : OAdoUser(_pParent,_bCase,_pUser)
{
}
// -------------------------------------------------------------------------
OUserExtend::OUserExtend(OCatalog* _pParent,sal_Bool _bCase, const ::rtl::OUString& _Name)
    : OAdoUser(_pParent,_bCase,_Name)
{
}

// -------------------------------------------------------------------------
void OUserExtend::construct()
{
    OUser_TYPEDEF::construct();
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD),    PROPERTY_ID_PASSWORD,0,&m_Password,::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
}
// -----------------------------------------------------------------------------
cppu::IPropertyArrayHelper* OUserExtend::createArrayHelper() const
{
    Sequence< com::sun::star::beans::Property > aProps;
    describeProperties(aProps);
    return new cppu::OPropertyArrayHelper(aProps);
}
// -------------------------------------------------------------------------
cppu::IPropertyArrayHelper & OUserExtend::getInfoHelper()
{
    return *OUserExtend_PROP::getArrayHelper();
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void SAL_CALL OAdoUser::acquire() throw(RuntimeException)
{
    OUser_TYPEDEF::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoUser::release() throw(RuntimeException)
{
    OUser_TYPEDEF::release();
}
// -----------------------------------------------------------------------------
sal_Int32 SAL_CALL OAdoUser::getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_TYPEDEF::rBHelper.bDisposed);

    return ADOS::mapAdoRights2Sdbc(m_aUser.GetPermissions(objName, ADOS::mapObjectType2Ado(objType)));
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL OAdoUser::getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_TYPEDEF::rBHelper.bDisposed);

    sal_Int32 nRights = 0;
    RightsEnum eRights = m_aUser.GetPermissions(objName, ADOS::mapObjectType2Ado(objType));
    if((eRights & adRightWithGrant) == adRightWithGrant)
        nRights = ADOS::mapAdoRights2Sdbc(eRights);
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
    return nRights;
}
// -------------------------------------------------------------------------
void SAL_CALL OAdoUser::grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_TYPEDEF::rBHelper.bDisposed);
    m_aUser.SetPermissions(objName,ADOS::mapObjectType2Ado(objType),adAccessGrant,RightsEnum(ADOS::mapRights2Ado(objPrivileges)));
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
}
// -------------------------------------------------------------------------
void SAL_CALL OAdoUser::revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_TYPEDEF::rBHelper.bDisposed);
    m_aUser.SetPermissions(objName,ADOS::mapObjectType2Ado(objType),adAccessRevoke,RightsEnum(ADOS::mapRights2Ado(objPrivileges)));
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
}
// -----------------------------------------------------------------------------
// XUser
void SAL_CALL OAdoUser::changePassword( const ::rtl::OUString& objPassword, const ::rtl::OUString& newPassword ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_TYPEDEF::rBHelper.bDisposed);
    m_aUser.ChangePassword(objPassword,newPassword);
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS mingwport03 (1.17.60); FILE MERGED 2006/11/07 12:31:52 vg 1.17.60.2: RESYNC: (1.17-1.18); FILE MERGED 2006/09/07 10:22:04 vg 1.17.60.1: #i53572# MinGW port<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AUser.cxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: vg $ $Date: 2007-03-26 13:58:39 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    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., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_connectivity.hxx"
#ifndef _CONNECTIVITY_ADO_USER_HXX_
#include "ado/AUser.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_CATALOG_HXX_
#include "ado/ACatalog.hxx"
#endif
#ifndef _CONNECTIVITY_ADO_GROUPS_HXX_
#include "ado/AGroups.hxx"
#endif
#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_
#include <cppuhelper/typeprovider.hxx>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBC_XROW_HPP_
#include <com/sun/star/sdbc/XRow.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XRESULTSET_HPP_
#include <com/sun/star/sdbc/XResultSet.hpp>
#endif
#ifndef _CONNECTIVITY_ADO_BCONNECTION_HXX_
#include "ado/AConnection.hxx"
#endif

#ifndef _CONNECTIVITY_ADO_AWRAPADO_HXX_
#include "ado/Awrapado.hxx"
#endif

using namespace connectivity::ado;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;

// -------------------------------------------------------------------------
OAdoUser::OAdoUser(OCatalog* _pParent,sal_Bool _bCase, ADOUser* _pUser)
    : OUser_TYPEDEF(_bCase)
    ,m_pCatalog(_pParent)
{
    construct();

    if(_pUser)
        m_aUser = WpADOUser(_pUser);
    else
        m_aUser.Create();
}
// -------------------------------------------------------------------------
OAdoUser::OAdoUser(OCatalog* _pParent,sal_Bool _bCase,   const ::rtl::OUString& _Name)
    : OUser_TYPEDEF(_Name,_bCase)
    , m_pCatalog(_pParent)
{
    construct();
    m_aUser.Create();
    m_aUser.put_Name(_Name);
}
// -------------------------------------------------------------------------
void OAdoUser::refreshGroups()
{
    TStringVector aVector;
    WpADOGroups aGroups(m_aUser.get_Groups());
    aGroups.fillElementNames(aVector);
    if(m_pGroups)
        m_pGroups->reFill(aVector);
    else
        m_pGroups = new OGroups(m_pCatalog,m_aMutex,aVector,aGroups,isCaseSensitive());
}
//--------------------------------------------------------------------------
Sequence< sal_Int8 > OAdoUser::getUnoTunnelImplementationId()
{
    static ::cppu::OImplementationId * pId = 0;
    if (! pId)
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        if (! pId)
        {
            static ::cppu::OImplementationId aId;
            pId = &aId;
        }
    }
    return pId->getImplementationId();
}

// com::sun::star::lang::XUnoTunnel
//------------------------------------------------------------------
sal_Int64 OAdoUser::getSomething( const Sequence< sal_Int8 > & rId ) throw (RuntimeException)
{
    return (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
                ? reinterpret_cast< sal_Int64 >( this )
                : OUser_TYPEDEF::getSomething(rId);
}

// -------------------------------------------------------------------------
void OAdoUser::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any& rValue)throw (Exception)
{
    if(m_aUser.IsValid())
    {

        switch(nHandle)
        {
            case PROPERTY_ID_NAME:
                {
                    ::rtl::OUString aVal;
                    rValue >>= aVal;
                    m_aUser.put_Name(aVal);
                }
                break;
        }
    }
}
// -------------------------------------------------------------------------
void OAdoUser::getFastPropertyValue(Any& rValue,sal_Int32 nHandle) const
{
    if(m_aUser.IsValid())
    {
        switch(nHandle)
        {
            case PROPERTY_ID_NAME:
                rValue <<= m_aUser.get_Name();
                break;
        }
    }
}
// -------------------------------------------------------------------------
OUserExtend::OUserExtend(OCatalog* _pParent,sal_Bool _bCase,    ADOUser* _pUser)
    : OAdoUser(_pParent,_bCase,_pUser)
{
}
// -------------------------------------------------------------------------
OUserExtend::OUserExtend(OCatalog* _pParent,sal_Bool _bCase, const ::rtl::OUString& _Name)
    : OAdoUser(_pParent,_bCase,_Name)
{
}

// -------------------------------------------------------------------------
void OUserExtend::construct()
{
    OUser_TYPEDEF::construct();
    registerProperty(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PASSWORD),    PROPERTY_ID_PASSWORD,0,&m_Password,::getCppuType(reinterpret_cast< ::rtl::OUString*>(NULL)));
}
// -----------------------------------------------------------------------------
cppu::IPropertyArrayHelper* OUserExtend::createArrayHelper() const
{
    Sequence< com::sun::star::beans::Property > aProps;
    describeProperties(aProps);
    return new cppu::OPropertyArrayHelper(aProps);
}
// -------------------------------------------------------------------------
cppu::IPropertyArrayHelper & OUserExtend::getInfoHelper()
{
    return *OUserExtend_PROP::getArrayHelper();
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void SAL_CALL OAdoUser::acquire() throw()
{
    OUser_TYPEDEF::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL OAdoUser::release() throw()
{
    OUser_TYPEDEF::release();
}
// -----------------------------------------------------------------------------
sal_Int32 SAL_CALL OAdoUser::getPrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed);

    return ADOS::mapAdoRights2Sdbc(m_aUser.GetPermissions(objName, ADOS::mapObjectType2Ado(objType)));
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL OAdoUser::getGrantablePrivileges( const ::rtl::OUString& objName, sal_Int32 objType ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed);

    sal_Int32 nRights = 0;
    RightsEnum eRights = m_aUser.GetPermissions(objName, ADOS::mapObjectType2Ado(objType));
    if((eRights & adRightWithGrant) == adRightWithGrant)
        nRights = ADOS::mapAdoRights2Sdbc(eRights);
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
    return nRights;
}
// -------------------------------------------------------------------------
void SAL_CALL OAdoUser::grantPrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed);
    m_aUser.SetPermissions(objName,ADOS::mapObjectType2Ado(objType),adAccessGrant,RightsEnum(ADOS::mapRights2Ado(objPrivileges)));
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
}
// -------------------------------------------------------------------------
void SAL_CALL OAdoUser::revokePrivileges( const ::rtl::OUString& objName, sal_Int32 objType, sal_Int32 objPrivileges ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed);
    m_aUser.SetPermissions(objName,ADOS::mapObjectType2Ado(objType),adAccessRevoke,RightsEnum(ADOS::mapRights2Ado(objPrivileges)));
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
}
// -----------------------------------------------------------------------------
// XUser
void SAL_CALL OAdoUser::changePassword( const ::rtl::OUString& objPassword, const ::rtl::OUString& newPassword ) throw(SQLException, RuntimeException)
{
    ::osl::MutexGuard aGuard(m_aMutex);
    checkDisposed(OUser_BASE_TYPEDEF::rBHelper.bDisposed);
    m_aUser.ChangePassword(objPassword,newPassword);
    ADOS::ThrowException(*m_pCatalog->getConnection()->getConnection(),*this);
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/power_save_blocker.h"

#include <windows.h>

#include "base/logging.h"
#include "content/public/browser/browser_thread.h"

using content::BrowserThread;

// Called only from UI thread.
// static
void PowerSaveBlocker::ApplyBlock(PowerSaveBlockerType type) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  DWORD flags = ES_CONTINUOUS;

  switch (type) {
    case kPowerSaveBlockPreventSystemSleep:
      flags |= ES_SYSTEM_REQUIRED;
      break;
    case kPowerSaveBlockPreventDisplaySleep:
      flags |= ES_DISPLAY_REQUIRED;
      break;
    default:
      break;
  }

  SetThreadExecutionState(flags);
}
<commit_msg>Content: Implement PowerSaveBlocker2 for windows.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/power_save_blocker.h"

#include <windows.h>

#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"
#include "content/public/browser/browser_thread.h"

using content::BrowserThread;

// Called only from UI thread.
// static
void PowerSaveBlocker::ApplyBlock(PowerSaveBlockerType type) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

  DWORD flags = ES_CONTINUOUS;

  switch (type) {
    case kPowerSaveBlockPreventSystemSleep:
      flags |= ES_SYSTEM_REQUIRED;
      break;
    case kPowerSaveBlockPreventDisplaySleep:
      flags |= ES_DISPLAY_REQUIRED;
      break;
    default:
      break;
  }

  SetThreadExecutionState(flags);
}

// TODO(rvargas): Remove after the old interface goes away.
#define PowerSaveBlocker PowerSaveBlocker2

namespace {

int g_blocker_count[2];

#if _WIN32_WINNT <= _WIN32_WINNT_WIN7
POWER_REQUEST_TYPE PowerRequestExecutionRequired =
    static_cast<POWER_REQUEST_TYPE>(PowerRequestAwayModeRequired + 1);
#endif

HANDLE CreatePowerRequest(POWER_REQUEST_TYPE type, const std::string& reason) {
  typedef HANDLE (WINAPI* PowerCreateRequestPtr)(PREASON_CONTEXT);
  typedef BOOL (WINAPI* PowerSetRequestPtr)(HANDLE, POWER_REQUEST_TYPE);

  if (type == PowerRequestExecutionRequired &&
      base::win::GetVersion() < base::win::VERSION_WIN8) {
    return INVALID_HANDLE_VALUE;
  }

  static PowerCreateRequestPtr PowerCreateRequestFn = NULL;
  static PowerSetRequestPtr PowerSetRequestFn = NULL;

  if (!PowerCreateRequestFn || !PowerSetRequestFn) {
    HMODULE module = GetModuleHandle(L"kernel32.dll");
    PowerCreateRequestFn = reinterpret_cast<PowerCreateRequestPtr>(
        GetProcAddress(module, "PowerCreateRequest"));
    PowerSetRequestFn = reinterpret_cast<PowerSetRequestPtr>(
        GetProcAddress(module, "PowerSetRequest"));

    if (!PowerCreateRequestFn || !PowerSetRequestFn)
      return INVALID_HANDLE_VALUE;
  }
  string16 wide_reason = ASCIIToUTF16(reason);
  REASON_CONTEXT context = {0};
  context.Version = POWER_REQUEST_CONTEXT_VERSION;
  context.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
  context.Reason.SimpleReasonString = const_cast<wchar_t*>(wide_reason.c_str());

  base::win::ScopedHandle handle(PowerCreateRequestFn(&context));
  if (!handle.IsValid())
    return INVALID_HANDLE_VALUE;

  if (PowerSetRequestFn(handle, type))
    return handle.Take();

  // Something went wrong.
  return INVALID_HANDLE_VALUE;
}

// Takes ownership of the |handle|.
void DeletePowerRequest(POWER_REQUEST_TYPE type, HANDLE handle) {
  base::win::ScopedHandle request_handle(handle);
  if (!request_handle.IsValid())
    return;

  if (type == PowerRequestExecutionRequired &&
      base::win::GetVersion() < base::win::VERSION_WIN8) {
    return;
  }

  typedef BOOL (WINAPI* PowerClearRequestPtr)(HANDLE, POWER_REQUEST_TYPE);
  HMODULE module = GetModuleHandle(L"kernel32.dll");
  PowerClearRequestPtr PowerClearRequestFn =
      reinterpret_cast<PowerClearRequestPtr>(
          GetProcAddress(module, "PowerClearRequest"));

  if (!PowerClearRequestFn)
    return;

  BOOL success = PowerClearRequestFn(request_handle, type);
  DCHECK(success);
}

void ApplySimpleBlock(content::PowerSaveBlocker::PowerSaveBlockerType type,
                      int delta) {
  g_blocker_count[type] += delta;
  DCHECK_GE(g_blocker_count[type], 0);

  if (g_blocker_count[type] > 1)
    return;

  DWORD this_flag = 0;
  if (type == content::PowerSaveBlocker::kPowerSaveBlockPreventAppSuspension)
    this_flag |= ES_SYSTEM_REQUIRED;
  else
    this_flag |= ES_DISPLAY_REQUIRED;

  DCHECK(this_flag);

  static DWORD flags = ES_CONTINUOUS;
  if (!g_blocker_count[type])
    flags &= ~this_flag;
  else
    flags |= this_flag;

  SetThreadExecutionState(flags);
}

}  // namespace.

namespace content {

class PowerSaveBlocker::Delegate
    : public base::RefCountedThreadSafe<PowerSaveBlocker::Delegate> {
 public:
  Delegate(PowerSaveBlockerType type, const std::string& reason)
      : type_(type), reason_(reason) {}

  // Does the actual work to apply or remove the desired power save block.
  void ApplyBlock();
  void RemoveBlock();

  // Returns the equivalent POWER_REQUEST_TYPE for this request.
  POWER_REQUEST_TYPE RequestType();

 private:
  friend class base::RefCountedThreadSafe<PowerSaveBlocker::Delegate>;
  ~Delegate() {}

  PowerSaveBlockerType type_;
  const std::string reason_;
  base::win::ScopedHandle handle_;

  DISALLOW_COPY_AND_ASSIGN(Delegate);
};

void PowerSaveBlocker::Delegate::ApplyBlock() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  base::win::Version os_version = base::win::GetVersion();
  if (os_version < base::win::VERSION_WIN7)
    return ApplySimpleBlock(type_, 1);

  handle_.Set(CreatePowerRequest(RequestType(), reason_));
}

void PowerSaveBlocker::Delegate::RemoveBlock() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  base::win::Version os_version = base::win::GetVersion();
  if (os_version < base::win::VERSION_WIN7)
    return ApplySimpleBlock(type_, -1);

  DeletePowerRequest(RequestType(), handle_.Take());
}

POWER_REQUEST_TYPE PowerSaveBlocker::Delegate::RequestType() {
  if (type_ == kPowerSaveBlockPreventDisplaySleep)
    return PowerRequestDisplayRequired;

  return PowerRequestExecutionRequired;
}

PowerSaveBlocker::PowerSaveBlocker(PowerSaveBlockerType type,
                                   const std::string& reason)
    : delegate_(new Delegate(type, reason)) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&Delegate::ApplyBlock, delegate_));
}

PowerSaveBlocker::~PowerSaveBlocker() {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&Delegate::RemoveBlock, delegate_));
}

}  // namespace content
<|endoftext|>