<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 <NAME> <<EMAIL>>
//

#include "FlightGearPositionProviderPlugin.h"

#include "MarbleDebug.h"
#include <math.h>

#include <QUdpSocket>

using namespace Marble;
/* TRANSLATOR Marble::FlightGearPositionProviderPlugin */

using namespace std;

FlightGearPositionProviderPlugin::FlightGearPositionProviderPlugin()
  : m_socket(0), m_speed( 0.0 ), m_track( 0.0 )
{
}

FlightGearPositionProviderPlugin::~FlightGearPositionProviderPlugin()
{
    delete m_socket;
}

QString FlightGearPositionProviderPlugin::name() const
{
    return tr( "FlightGear position provider Plugin" );
}

QString FlightGearPositionProviderPlugin::nameId() const
{
    return QString::fromLatin1( "flightgear" );
}

QString FlightGearPositionProviderPlugin::guiString() const
{
    return tr( "FlightGear" );
}

QString FlightGearPositionProviderPlugin::version() const
{
    return "1.0";
}

QString FlightGearPositionProviderPlugin::description() const
{
    return tr( "Reports the position of running flightgear application." );
}

QString FlightGearPositionProviderPlugin::copyrightYears() const
{
    return "2012";
}

QList<PluginAuthor> FlightGearPositionProviderPlugin::pluginAuthors() const
{
    return QList<PluginAuthor>()
            << PluginAuthor( QString::fromUtf8( "<NAME>" ), "<EMAIL>" );

}

QIcon FlightGearPositionProviderPlugin::icon() const
{
    return QIcon();
}

void FlightGearPositionProviderPlugin::initialize()
{
    m_status = PositionProviderStatusAcquiring;
    emit statusChanged( m_status );

    m_socket = new QUdpSocket(this);
    m_socket->bind(QHostAddress::LocalHost, 5500);

    connect(m_socket, SIGNAL(readyRead()),
             this, SLOT(readPendingDatagrams()));
}

/**
 fixed case where wrong date format is used '2404112' instead of '240412'
*/
bool fixBadGPRMC(QByteArray &line)
{
    if (!line.startsWith("$GPRMC"))
        return false;

    QStringList parts = QString(line).split(',');
    if (parts[9].size() == 7) {
        parts[9].remove(4,1);
        line = parts.join(",").toLatin1();
        // update crc
        int crc = 0;
        for(int i=1; i < line.size()-3; i++) {
            crc ^= (int) line[i];
        }
        parts[11] = parts[11][0] + parts[11][1] +  QString::number(crc, 16).toUpper();

        line = parts.join(",").toLatin1();
        return true;
    }
    return false;
}

void FlightGearPositionProviderPlugin::readPendingDatagrams()
{
    while (m_socket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(m_socket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        m_socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        typedef QList<QByteArray>::Iterator Iterator;
        QList<QByteArray> splitted = datagram.split('\n');
        for (Iterator i = splitted.begin(); i != splitted.end(); i++) {
            fixBadGPRMC(*i);
            *i->append( "\n" );
            parseNmeaSentence( *i );
        }
    }
}

void FlightGearPositionProviderPlugin::parseNmeaSentence( const QString &sentence )
{
    PositionProviderStatus oldStatus = m_status;
    GeoDataCoordinates oldPosition = m_position;

    if ( sentence.startsWith( QLatin1String( "$GPRMC" ) ) ) {
        QStringList const values = sentence.split( ',' );
        if ( values.size() > 9 ) {
            if ( values[2] == "A" ) {
                m_speed = values[7].toDouble() * 0.514444; // knots => m/s
                m_track = values[8].toDouble();
                QString const date = values[9] + ' ' + values[1];
                m_timestamp = QDateTime::fromString( date, "ddMMyy HHmmss" );
                if (m_timestamp.date().year() <= 1930 && m_timestamp.date().year() >= 1900 ) {
                    m_timestamp = m_timestamp.addYears( 100 ); // Qt range is 1900-1999 for two-digits
                }
            }
            // Flightgear submits geoposition twice in one datagram, once
            // in GPRMC and once in GPGGA. Parsing one is sufficient
        }
    } else if ( sentence.startsWith( QLatin1String( "$GPGGA" ) ) ) {
        QStringList const values = sentence.split( ',' );
        if ( values.size() > 10 ) {
            if ( values[6] == 0 ) {
                m_status = PositionProviderStatusUnavailable; // no fix<commit_msg>No need to create an unused local copy.<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2012 <NAME> <<EMAIL>>
//

#include "FlightGearPositionProviderPlugin.h"

#include "MarbleDebug.h"
#include <math.h>

#include <QUdpSocket>

using namespace Marble;
/* TRANSLATOR Marble::FlightGearPositionProviderPlugin */

using namespace std;

FlightGearPositionProviderPlugin::FlightGearPositionProviderPlugin()
  : m_socket(0), m_speed( 0.0 ), m_track( 0.0 )
{
}

FlightGearPositionProviderPlugin::~FlightGearPositionProviderPlugin()
{
    delete m_socket;
}

QString FlightGearPositionProviderPlugin::name() const
{
    return tr( "FlightGear position provider Plugin" );
}

QString FlightGearPositionProviderPlugin::nameId() const
{
    return QString::fromLatin1( "flightgear" );
}

QString FlightGearPositionProviderPlugin::guiString() const
{
    return tr( "FlightGear" );
}

QString FlightGearPositionProviderPlugin::version() const
{
    return "1.0";
}

QString FlightGearPositionProviderPlugin::description() const
{
    return tr( "Reports the position of running flightgear application." );
}

QString FlightGearPositionProviderPlugin::copyrightYears() const
{
    return "2012";
}

QList<PluginAuthor> FlightGearPositionProviderPlugin::pluginAuthors() const
{
    return QList<PluginAuthor>()
            << PluginAuthor( QString::fromUtf8( "<NAME>" ), "<EMAIL>" );

}

QIcon FlightGearPositionProviderPlugin::icon() const
{
    return QIcon();
}

void FlightGearPositionProviderPlugin::initialize()
{
    m_status = PositionProviderStatusAcquiring;
    emit statusChanged( m_status );

    m_socket = new QUdpSocket(this);
    m_socket->bind(QHostAddress::LocalHost, 5500);

    connect(m_socket, SIGNAL(readyRead()),
             this, SLOT(readPendingDatagrams()));
}

/**
 fixed case where wrong date format is used '2404112' instead of '240412'
*/
bool fixBadGPRMC(QByteArray &line)
{
    if (!line.startsWith("$GPRMC"))
        return false;

    QStringList parts = QString(line).split(',');
    if (parts[9].size() == 7) {
        parts[9].remove(4,1);
        line = parts.join(",").toLatin1();
        // update crc
        int crc = 0;
        for(int i=1; i < line.size()-3; i++) {
            crc ^= (int) line[i];
        }
        parts[11] = parts[11][0] + parts[11][1] +  QString::number(crc, 16).toUpper();

        line = parts.join(",").toLatin1();
        return true;
    }
    return false;
}

void FlightGearPositionProviderPlugin::readPendingDatagrams()
{
    while (m_socket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(m_socket->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        m_socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);
        typedef QList<QByteArray>::Iterator Iterator;
        QList<QByteArray> splitted = datagram.split('\n');
        for (Iterator i = splitted.begin(); i != splitted.end(); i++) {
            fixBadGPRMC(*i);
            i->append( "\n" );
            parseNmeaSentence( *i );
        }
    }
}

void FlightGearPositionProviderPlugin::parseNmeaSentence( const QString &sentence )
{
    PositionProviderStatus oldStatus = m_status;
    GeoDataCoordinates oldPosition = m_position;

    if ( sentence.startsWith( QLatin1String( "$GPRMC" ) ) ) {
        QStringList const values = sentence.split( ',' );
        if ( values.size() > 9 ) {
            if ( values[2] == "A" ) {
                m_speed = values[7].toDouble() * 0.514444; // knots => m/s
                m_track = values[8].toDouble();
                QString const date = values[9] + ' ' + values[1];
                m_timestamp = QDateTime::fromString( date, "ddMMyy HHmmss" );
                if (m_timestamp.date().year() <= 1930 && m_timestamp.date().year() >= 1900 ) {
                    m_timestamp = m_timestamp.addYears( 100 ); // Qt range is 1900-1999 for two-digits
                }
            }
            // Flightgear submits geoposition twice in one datagram, once
            // in GPRMC and once in GPGGA. Parsing one is sufficient
        }
    } else if ( sentence.startsWith( QLatin1String( "$GPGGA" ) ) ) {
        QStringList const values = sentence.split( ',' );
        if ( values.size() > 10 ) {
            if ( values[6] == 0 ) {
                m_status = PositionProviderStatusUnavailable; // no fix
{'fraction_non_alphanumeric': 0.13106102253985707, 'fraction_numerical': 0.020670698185816384, 'mean_word_length': 3.00881445570736, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6442656', 'n_tokens_mistral': 2939, 'n_tokens_neox': 2800, 'n_words': 642}