<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
 *
 */

/**
 * @interface FsoFramework.CommandQueue
 **/
public abstract interface FsoFramework.CommandQueue : GLib.Object
{
    public delegate void UnsolicitedHandler( string prefix, string response, string? pdu = null );

    /**
     * The underlying transport
     **/
    public abstract Transport transport { get; set; }
    /**
     * Open the command queue
     **/
    public abstract async bool open();
    /**
     * Close the command queue
     **/
    public abstract async void close();
    /**
     * Register @a UnsolicitedHandler delegate that will be called for incoming URCs
     **/
    public abstract void registerUnsolicitedHandler( UnsolicitedHandler urchandler );
    /**
     * Halt the Queue operation. Stop accepting any more commands. If drain is true, send
     * all commands that are in the Queue at this point.
     **/
    public abstract async void freeze( bool drain = false );
    /**
     * Resume the Queue operation.
     **/
    public abstract async void thaw();
}

/**
 * @class FsoFramework.AbstractCommandHandler
 **/
public abstract class FsoFramework.AbstractCommandHandler
{
    public uint timeout;
    public uint retry;
    public SourceFunc callback;

    public abstract void writeToTransport( FsoFramework.Transport t );
    public abstract string to_string();
}

/**
 * @class FsoFramework.AbstractCommandQueue
 **/
public abstract class FsoFramework.AbstractCommandQueue : FsoFramework.CommandQueue, GLib.Object
{
    /**
     * @property transport - The underlying transport
     **/
    public Transport transport { get; set; }
    /**
     * Sent, when an error has occured
     **/
    public signal void hangup();

    //
    // private API
    //
    private Gee.LinkedList<AbstractCommandHandler> q;
    private uint timeoutWatch;

    //
    // protected API
    //
    protected FsoFramework.CommandQueue.UnsolicitedHandler urchandler;
    protected AbstractCommandHandler current;
    protected abstract void onReadFromTransport( FsoFramework.Transport t );
    protected abstract void onResponseTimeout( AbstractCommandHandler ach );

    protected bool checkRestartingQ()
    {
        if ( current == null && q.size > 0 )
        {
            writeNextCommand();
            return true;
        }
        else
        {
            return false;
        }
    }

    protected void writeNextCommand()
    {
        current = q.poll_head();
        current.writeToTransport( transport );
        assert( transport.logger.debug( @"Wrote '$current'. Waiting ($(current.timeout)s) for answer..." ) );
        if ( current.timeout > 0 )
        {
            timeoutWatch = GLib.Timeout.add_seconds( current.timeout, onTimeout );
        }
    }

    protected void resetTimeout()
    {
        if ( timeoutWatch > 0 )
        {
            GLib.Source.remove( timeoutWatch );
        }
    }

    protected void onHupFromTransport()
    {
        transport.logger.warning( "HUP from transport." );
        this.hangup(); // emit HUP signal
    }

    protected bool onTimeout()
    {
        assert( transport.logger.warning( @"Timeout while waiting for an answer to '$current'" ) );
        if ( current.retry > 0 )
        {
            current.retry--;
            assert( transport.logger.debug( @"Retrying '$current', retry counter = $(current.retry)" ) );
            current.writeToTransport( transport );
            return true; // call me again
        }
        else
        {
            onResponseTimeout( current ); // derived class is responsible for relaunching the command queue
        }
        return false; // don't call me again
    }

    protected void enqueueCommand( AbstractCommandHandler command )
    {
        q.offer_tail( command );
        Idle.add( checkRestartingQ );
    }

    protected void reset()
    {
        transport.logger.info( "Reset commandqueue ..." );
        current = null;
        q.clear();
    }

    //
    // public API<commit_msg>libfsotransport: command queue: provide empty default implementation for onResponseTimeout()<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
 *
 */

/**
 * @interface FsoFramework.CommandQueue
 **/
public abstract interface FsoFramework.CommandQueue : GLib.Object
{
    public delegate void UnsolicitedHandler( string prefix, string response, string? pdu = null );

    /**
     * The underlying transport
     **/
    public abstract Transport transport { get; set; }
    /**
     * Open the command queue
     **/
    public abstract async bool open();
    /**
     * Close the command queue
     **/
    public abstract async void close();
    /**
     * Register @a UnsolicitedHandler delegate that will be called for incoming URCs
     **/
    public abstract void registerUnsolicitedHandler( UnsolicitedHandler urchandler );
    /**
     * Halt the Queue operation. Stop accepting any more commands. If drain is true, send
     * all commands that are in the Queue at this point.
     **/
    public abstract async void freeze( bool drain = false );
    /**
     * Resume the Queue operation.
     **/
    public abstract async void thaw();
}

/**
 * @class FsoFramework.AbstractCommandHandler
 **/
public abstract class FsoFramework.AbstractCommandHandler
{
    public uint timeout;
    public uint retry;
    public SourceFunc callback;

    public abstract void writeToTransport( FsoFramework.Transport t );
    public abstract string to_string();
}

/**
 * @class FsoFramework.AbstractCommandQueue
 **/
public abstract class FsoFramework.AbstractCommandQueue : FsoFramework.CommandQueue, GLib.Object
{
    /**
     * @property transport - The underlying transport
     **/
    public Transport transport { get; set; }
    /**
     * Sent, when an error has occured
     **/
    public signal void hangup();

    //
    // private API
    //
    private Gee.LinkedList<AbstractCommandHandler> q;
    private uint timeoutWatch;

    //
    // protected API
    //
    protected FsoFramework.CommandQueue.UnsolicitedHandler urchandler;
    protected AbstractCommandHandler current;
    protected abstract void onReadFromTransport( FsoFramework.Transport t );

    protected bool checkRestartingQ()
    {
        if ( current == null && q.size > 0 )
        {
            writeNextCommand();
            return true;
        }
        else
        {
            return false;
        }
    }

    protected void writeNextCommand()
    {
        current = q.poll_head();
        current.writeToTransport( transport );
        assert( transport.logger.debug( @"Wrote '$current'. Waiting ($(current.timeout)s) for answer..." ) );
        if ( current.timeout > 0 )
        {
            timeoutWatch = GLib.Timeout.add_seconds( current.timeout, onTimeout );
        }
    }

    protected void resetTimeout()
    {
        if ( timeoutWatch > 0 )
        {
            GLib.Source.remove( timeoutWatch );
        }
    }

    protected void onHupFromTransport()
    {
        transport.logger.warning( "HUP from transport." );
        this.hangup(); // emit HUP signal
    }

    protected bool onTimeout()
    {
        assert( transport.logger.warning( @"Timeout while waiting for an answer to '$current'" ) );
        if ( current.retry > 0 )
        {
            current.retry--;
            assert( transport.logger.debug( @"Retrying '$current', retry counter = $(current.retry)" ) );
            current.writeToTransport( transport );
            return true; // call me again
        }
        else
        {
            onResponseTimeout( current ); // derived class is responsible for relaunching the command queue
        }
        return false; // don't call me again
    }

    protected virtual void onResponseTimeout( AbstractCommandHandler ach )
    {
    }

    protected void enqueueCommand( AbstractCommandHandler command )
    {
        q.offer_tail( command );
        Idle.add( checkRestartingQ );
    }

    protected void reset()
    {
        transport.logger.info( "Reset commandqueue ..." );
        current = null;
        q.clear();
    }

    //
    // public API
{'fraction_non_alphanumeric': 0.09039020340390204, 'fraction_numerical': 0.00518887505188875, 'mean_word_length': 2.419801277501774, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, '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': '2881907', 'n_tokens_mistral': 2538, 'n_tokens_neox': 2450, 'n_words': 871}