#include "bautils.h"
// Wymagana biblioteka: bafl.lib

/**
* Funkcja dopisuje dane do koca pliku dane.dat zlokalizowanego
* w katalogu prywatnym procesu. Jeeli plik lub katalog prywatny
* nie istnieje - zostanie utworzony przed zapisem danych.
*/
TInt DopiszDoPliku( const TDesC8& aDane )
{
    RFs systemPlikow;
    TInt blad = systemPlikow.Connect();
    
    if( blad == KErrNone )
    {
        TBuf< 64 > plikChroniony;
        blad = systemPlikow.PrivatePath( plikChroniony );
        
        if( blad == KErrNone )
        {
            // Dla procesu posiadajcego identyfikator SID = 0xe77b46fb
            // katalog prywatny ma nastpujc posta:
            // katalogPrywatny = "\\Private\\e77b46fb\\"
            
            _LIT( KDyskC, "c:" );
            plikChroniony.Insert( 0, KDyskC );
            // katalogPrywatny = "c:\\Private\\e77b46fb\\"
            
            // Sprawdzamy, czy katalog istnieje. 
            if( !BaflUtils::FolderExists( systemPlikow, plikChroniony ) )
            {
                // Katalog nie istnieje - tworzymy go. 
                blad = systemPlikow.CreatePrivatePath( EDriveC );
            }
            
            if( blad == KErrNone )
            {
                // Finalizujemy komponowanie cieki do pliku.
                _LIT( KNazwaPliku, "dane.dat" );
                plikChroniony.Append( KNazwaPliku );
                // katalogPrywatny = "c:\\Private\\e77b46fb\\dane.dat"
                
                // Otwieramy plik.
                RFile plik;
                blad = plik.Open( systemPlikow, plikChroniony, EFileWrite );
                
                if( blad == KErrNone )
                {
                    // Udao si otworzy plik - ustawiamy si na jego kocu
                    // wzgldem koca pliku.
                    TInt pozycja = 0;    
                    blad = plik.Seek( ESeekEnd, pozycja );
                }
                else
                {
                    blad = plik.Create( systemPlikow, plikChroniony,
                             EFileWrite );
                }
                
                if( blad == KErrNone )
                {
                    // Zapisujemy dane do pliku.
                    plik.Write( aDane );
                }
                
                plik.Close();
            }
        }
        
        systemPlikow.Close();
    }
    
    return blad;
}

// Funkcje wtkw
TInt FunkcjaWatkuPierwszego( TAny* aPtr )
{    
    HBufC8* dane = NULL;
    // Przygotowanie danych do zapisu...
    
    RMutex* muteks = static_cast< RMutex* >( aPtr );
    muteks->Wait();
    TInt blad = DopiszDoPliku( *dane );
    muteks->Signal();
    
    delete dane;
    return blad;
}

TInt FunkcjaWatkuDrugiego( TAny* aPtr )
{
    HBufC8* dane = NULL;
    // Przygotowanie danych do zapisu...
    
    RMutex* muteks = static_cast< RMutex* >( aPtr );
    muteks->Wait();
    TInt blad = DopiszDoPliku( *dane );
    muteks->Signal();
    
    delete dane;
    return blad;
}

// ----------------------------------
// ------ Wtek gwny procesu ------
// ----------------------------------

// Tworzymy muteks do synchronizacji wtkw w biecym procesie.
User::LeaveIfError( iMuteks.CreateLocal() );

// Tworzymy wtki.
_LIT( KPierwszyWatek, "Watek1" );
_LIT( KDrugiWatek, "Watek2" );

TInt blad = iPierwszyWatek.Create( KPierwszyWatek, 
                    FunkcjaWatkuPierwszego,
                    KDefaultStackSize,
                    NULL,    // aHeap = NULL, uywamy sterty wtku gwnego.
                    static_cast<TAny*>( &iMuteks ) );
User::LeaveIfError( blad );

blad = iDrugiWatek.Create( KDrugiWatek, 
                FunkcjaWatkuDrugiego,
                KDefaultStackSize,
                NULL,    // aHeap = NULL, uywamy sterty wtku gwnego.
                static_cast<TAny*>( &iMuteks ) );
User::LeaveIfError( blad );

// Oba wtki zostay utworzone pomylnie.
iPierwszyWatek.Resume();
iDrugiWatek.Resume();
