/*
 * KryptografAsync.h
 *
 * Autor: Pawe Gala
 */

#ifndef __KRYPTOGRAFASYNC_H__
#define __KRYPTOGRAFASYNC_H__

#include <e32base.h>
#include "Kryptograf.h"

class CKryptografAsync : public CActive
    {
public:
    // Wewntrzny stan kryptografa
    enum TStatus
        {
        EBezczynny,
        ESzyfrowanie,
        EDeszyfrowanie
        };
    
public:        // Konstruktor i destruktor
    CKryptografAsync();
    ~CKryptografAsync();
    
public:
    TInt Szyfruj( const RMessage2& aMessage );
    TInt Deszyfruj( const RMessage2& aMessage );
    
    inline HBufC8* DaneOdszyf() { return iDaneOdszyf; }
    inline HBufC8* DaneZaszyf() { return iDaneZaszyf; }
    
    inline TStatus StatOperacji() { return iStatOperacji; }
    
private:    // Odziedziczone z CActive
    void DoCancel();
    void RunL();
    
private:
    void Reset();

private:    // Pola
    RThread iWatek;
    TStatus iStatOperacji;
    
    RMessage2 iMessage;
    HBufC8* iDaneOdszyf;
    HBufC8* iDaneZaszyf;
    };

#endif /* KRYPTOGRAFASYNC_H_ */


/*
 * KryptografAsync.cpp
 *
 * Autor: Pawe Gala
 */

#include "KryptografAsync.h"

_LIT( KNazwaWatku, "KryptografAsync" );


TInt FunkcjaWatku( TAny* aPtr )
    {
    CKryptografAsync* kryptografAsync = ( CKryptografAsync* )aPtr;
    TKryptograf kryptograf;
    
    TPtr8 daneOdszyfWsk = kryptografAsync->DaneOdszyf()->Des();
    TPtr8 daneZaszyfWsk = kryptografAsync->DaneZaszyf()->Des();
    
    TInt blad = KErrNone;
    if( kryptografAsync->StatOperacji() == CKryptografAsync::ESzyfrowanie )
        {
        blad = kryptograf.Szyfruj( daneOdszyfWsk, daneZaszyfWsk );
        }
    if( kryptografAsync->StatOperacji() == CKryptografAsync::EDeszyfrowanie )
        {
        blad = kryptograf.Deszyfruj( daneZaszyfWsk, daneOdszyfWsk );
        }
    return blad;
    }

CKryptografAsync::CKryptografAsync() : CActive( EPriorityStandard )
    {
    CActiveScheduler::Add( this );
    }
    
CKryptografAsync::~CKryptografAsync()
    {
    Cancel();
    Reset();
    }
    
TInt CKryptografAsync::Szyfruj( const RMessage2& aMessage )
    {
    TInt blad = KErrInUse;
    if( !IsActive() )
        {
        Reset();
        iMessage = aMessage;
        
        iDaneOdszyf = HBufC8::NewL( aMessage.GetDesLength( 0 ) );
        iDaneZaszyf = HBufC8::NewL( aMessage.GetDesMaxLengthL( 1 ) );
        
        TPtr8 daneOdszfWsk = iDaneOdszyf->Des();
        blad = aMessage.Read( 0, daneOdszfWsk, 0 );
        if( blad == KErrNone )
            {
            // Tworzymy unikaln nazw wtku.
            TBuf< 32 > nazwaWatku( KNazwaWatku );
            nazwaWatku.AppendNum( (TUint)iDaneOdszyf );
            
            blad = iWatek.Create( nazwaWatku,
                        FunkcjaWatku,
                        KDefaultStackSize,
                        NULL,
                        ( TAny* )this );
            
            if( blad == KErrNone )
                {
                iStatOperacji = ESzyfrowanie;
                iWatek.Resume();
    
                iWatek.Logon( iStatus );
                SetActive();
                }
            }
        }
    
    return blad;
    }

TInt CKryptografAsync::Deszyfruj( const RMessage2& aMessage )
    {
    TInt blad = KErrInUse;
    if( !IsActive() )
        {
        Reset();
        iMessage = aMessage;
        
        iDaneZaszyf = HBufC8::NewL( aMessage.GetDesLength( 0 ) );
        iDaneOdszyf = HBufC8::NewL( aMessage.GetDesMaxLengthL( 1 ) );
        
        TPtr8 daneZaszfWsk = iDaneZaszyf->Des();
        blad = aMessage.Read( 0, daneZaszfWsk, 0 );
        if( blad == KErrNone )
            {
            // Tworzymy unikaln nazw wtku.
            TBuf< 32 > nazwaWatku( KNazwaWatku );
            nazwaWatku.AppendNum( (TUint)iDaneZaszyf );
            
            blad = iWatek.Create( nazwaWatku,
                        FunkcjaWatku,
                        KDefaultStackSize,
                        NULL,
                        ( TAny* )this );
            
            if( blad == KErrNone )
                {
                iStatOperacji = EDeszyfrowanie;
                iWatek.Resume();
    
                iWatek.Logon( iStatus );
                SetActive();
                }
            }
        }
    
    return blad;
    }
    
void CKryptografAsync::DoCancel()
    {
    iWatek.LogonCancel( iStatus );
    iWatek.Terminate( KErrCancel );
    Reset();
    
    iMessage.Complete( KErrCancel );
    }

void CKryptografAsync::RunL()
    {
    HBufC8* dane = NULL;
    if( iStatOperacji == ESzyfrowanie )
        {
        dane = iDaneZaszyf;
        }
    else if( iStatOperacji == EDeszyfrowanie )
        {
        dane = iDaneOdszyf;
        }
    else
        {
        User::Leave( KErrAbort );
        }
    
    TInt blad = iWatek.ExitReason();
    if( blad == KErrNone && dane != NULL )
        {
        TPtr8 daneWsk( dane->Des() );
        blad = iMessage.Write( 1, daneWsk, 0 );
        }
    
    iMessage.Complete( blad );
    }

void CKryptografAsync::Reset()
    {
    iWatek.Close();
    
    delete iDaneOdszyf;
    iDaneOdszyf = NULL;
    
    delete iDaneZaszyf;
    iDaneZaszyf = NULL;
    
    iStatOperacji = EBezczynny;
    }
