<commit_before>/*
 * Copyright (C) 2009-2010 Michael 'Mickey' Lauer <<EMAIL>>
 *
 * 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
 *
 */

using GLib;

public delegate void StringInVoidOutFunc( string str );

namespace Nmea {
    const string MODULE_NAME = "fsotdl.source_gps_nmea";
    const string CHANNEL_NAME = "NMEA";
}

class Nmea.Receiver : FsoGps.AbstractReceiver
{
    private Nmea.Protocol protocol;

    public override string repr()
    {
        return "<>";
    }

    protected override void createChannels()
    {
        var transport = FsoFramework.Transport.create( receiver_transport, receiver_port, receiver_speed );
        var parser = new FsoFramework.LineByLineParser();
        var chan = new FsoGps.Channel( CHANNEL_NAME, transport, parser );

        protocol = new Nmea.Protocol( this );
    }

    public override void processUnsolicitedResponse( string prefix, string righthandside, string? pdu = null )
    {
        message( @"NMEA DATUM: $righthandside" );
        assert( protocol != null );
        if ( righthandside.length > 6 )
        {
            protocol.feed( righthandside );
        }
    }
}

public class Nmea.DelegateAndRegex
{
    public StringInVoidOutFunc func;
    public GLib.Regex re;

    public DelegateAndRegex( owned StringInVoidOutFunc func, owned GLib.Regex re )
    {
        this.func = func;
        this.re = re;
    }
}

class Nmea.Protocol : Object
{
    private Gee.HashMap<string,Nmea.DelegateAndRegex> delegates;
    private GLib.MatchInfo mi;
    private FsoGps.AbstractReceiver receiver;

    private bool match( GLib.Regex re, string str )
    {
        bool match;
        match = re.match( str, 0, out mi );
        return ( match ) ? mi != null : false;
    }

    private T to<T>( string name )
    {
        var res = mi.fetch_named( name );

        if ( typeof(T) == typeof(int) )
        {
            message( "%s: %d", name, res.to_int() );
            return ( res == null ) ? 0 : res.to_int();
        }
        else if ( typeof(T) == typeof(string) )
        {
            return ( res == null ) ? "" : res;
        }
        /* not possible due to bug in vala
        else if ( typeof(T) == typeof(double) )
        {
            return ( res == null ) ? 0.0 : res.to_double();
        }
        */
        else
        {
            assert_not_reached();
        }
    }

    public void onGpzda( string datum )
    {
        GLib.Time t = {};
        t.hour = to<int>( "hour" );
        t.minute = to<int>( "minute" );
        t.second = to<int>( "second" );
        t.day = to<int>( "day" );
        t.month = to<int>( "month" ) - 1;
        t.year = to<int>( "year" ) - 1900;

        var zoneh = to<int>( "zoneh" );
        var zonem = to<int>( "zonem" );

        var epoch = Linux.timegm( t );
#if DEBUG
        debug( "GPZDA reports %d".printf( (int)epoch ) );
#endif
    }

    public void onGpgsv( string datum )
    {
        int numsats = to<int>( "numsats" );
        debug( @"GPGSV reports $numsats sats in view" );
    }

    public void onGprmc( string datum )
    {
        bool valid = ( to<string>( "valid" ) == "A" );
        if ( !valid )
        {
            return;
        }

        var report = new GLib.HashTable<string,Value?>( str_hash, str_equal );

        double lat = to<int>( "latdd" ) + to<string>( "lat" ).to_double() / 60;
        double lon = to<int>( "londd" ) + to<string>( "lon" ).to_double() / 60;

        debug( @"GPRMC reports location %.6f N + %.6f E".printf( lat, lon ) );

        report.insert( "lat", lat );
        report.insert( "lon", lon );

        receiver.location( receiver, report );<commit_msg>fsotdld: provider_gps_nmea: use full keynames<commit_after>/*
 * Copyright (C) 2009-2010 Michael 'Mickey' Lauer <<EMAIL>>
 *
 * 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
 *
 */

using GLib;

public delegate void StringInVoidOutFunc( string str );

namespace Nmea {
    const string MODULE_NAME = "fsotdl.source_gps_nmea";
    const string CHANNEL_NAME = "NMEA";
}

class Nmea.Receiver : FsoGps.AbstractReceiver
{
    private Nmea.Protocol protocol;

    public override string repr()
    {
        return "<>";
    }

    protected override void createChannels()
    {
        var transport = FsoFramework.Transport.create( receiver_transport, receiver_port, receiver_speed );
        var parser = new FsoFramework.LineByLineParser();
        var chan = new FsoGps.Channel( CHANNEL_NAME, transport, parser );

        protocol = new Nmea.Protocol( this );
    }

    public override void processUnsolicitedResponse( string prefix, string righthandside, string? pdu = null )
    {
        message( @"NMEA DATUM: $righthandside" );
        assert( protocol != null );
        if ( righthandside.length > 6 )
        {
            protocol.feed( righthandside );
        }
    }
}

public class Nmea.DelegateAndRegex
{
    public StringInVoidOutFunc func;
    public GLib.Regex re;

    public DelegateAndRegex( owned StringInVoidOutFunc func, owned GLib.Regex re )
    {
        this.func = func;
        this.re = re;
    }
}

class Nmea.Protocol : Object
{
    private Gee.HashMap<string,Nmea.DelegateAndRegex> delegates;
    private GLib.MatchInfo mi;
    private FsoGps.AbstractReceiver receiver;

    private bool match( GLib.Regex re, string str )
    {
        bool match;
        match = re.match( str, 0, out mi );
        return ( match ) ? mi != null : false;
    }

    private T to<T>( string name )
    {
        var res = mi.fetch_named( name );

        if ( typeof(T) == typeof(int) )
        {
            message( "%s: %d", name, res.to_int() );
            return ( res == null ) ? 0 : res.to_int();
        }
        else if ( typeof(T) == typeof(string) )
        {
            return ( res == null ) ? "" : res;
        }
        /* not possible due to bug in vala
        else if ( typeof(T) == typeof(double) )
        {
            return ( res == null ) ? 0.0 : res.to_double();
        }
        */
        else
        {
            assert_not_reached();
        }
    }

    public void onGpzda( string datum )
    {
        GLib.Time t = {};
        t.hour = to<int>( "hour" );
        t.minute = to<int>( "minute" );
        t.second = to<int>( "second" );
        t.day = to<int>( "day" );
        t.month = to<int>( "month" ) - 1;
        t.year = to<int>( "year" ) - 1900;

        var zoneh = to<int>( "zoneh" );
        var zonem = to<int>( "zonem" );

        var epoch = Linux.timegm( t );
#if DEBUG
        debug( "GPZDA reports %d".printf( (int)epoch ) );
#endif
    }

    public void onGpgsv( string datum )
    {
        int numsats = to<int>( "numsats" );
        debug( @"GPGSV reports $numsats sats in view" );
    }

    public void onGprmc( string datum )
    {
        bool valid = ( to<string>( "valid" ) == "A" );
        if ( !valid )
        {
            return;
        }

        var report = new GLib.HashTable<string,Value?>( str_hash, str_equal );

        double lat = to<int>( "latdd" ) + to<string>( "lat" ).to_double() / 60;
        double lon = to<int>( "londd" ) + to<string>( "lon" ).to_double() / 60;

        debug( @"GPRMC reports location %.6f N + %.6f E".printf( lat, lon ) );

        report.insert( "latitude", lat );
        report.insert( "longitude", lon );

        receiver.location( receiver, report );
{'fraction_non_alphanumeric': 0.11748476836417979, 'fraction_numerical': 0.0085067249109093, 'mean_word_length': 2.2329988851727984, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 45, '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': '4548476', 'n_tokens_mistral': 2767, 'n_tokens_neox': 2650, 'n_words': 842}