⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 poruka.cpp

📁 load data from pc to hand held terminal and vice versa
💻 CPP
字号:
/*
    Klase za rad sa porukama.
*/
#include "Poruka.h"
#include "Korisno.h"
#include "Konfig.h"
#include <iostream>

//*********************************** KPoruka << BEGIN >> ***************************************
// Konstruktori
KPoruka::KPoruka( string cSadrzajPoruke, KFormatPoruke& formatPoruke ) {
    KPoruka::format = formatPoruke;
    PostaviSadrzaj( cSadrzajPoruke );
}

KPoruka::KPoruka( string cSadrzajPoruke, IDFormataPoruke formatID ){
    KFormatPoruke format;

    // Ako dati format ne postoji kreiraj poruku sa DEFAULT formatom
    if ( !KSpisakFormata::Instance()->DajFormatPoruke( formatID, format ) )
        KSpisakFormata::Instance()->DajDefaultFormat( format );

    auto_ptr<KPoruka> pPoruka( new KPoruka( cSadrzajPoruke, format ) );
    ( *this ) = *pPoruka;
}

// Default konstruktor
KPoruka::KPoruka( IDFormataPoruke formatID ){
    auto_ptr<KPoruka> pPoruka( new KPoruka( "", formatID ) );
    ( *this ) = *pPoruka;
}

// Vraca duzinu poruke
int KPoruka::Duzina( void ) const {
    return sadrzaj.size();
}

// Vraca sadrzaj poruke
string KPoruka::Sadrzaj( void ){
    return KPoruka::sadrzaj;
};

// Vraca format poruke
KFormatPoruke KPoruka::Format( void ) const {
    return KPoruka::format;
}

// Procedura postavlja sadrzaj poruke.
void KPoruka::PostaviSadrzaj( string cNoviSadrzaj ) {
    KPoruka::sadrzaj = cNoviSadrzaj;
    // Postavi pozicije i duzine pojedinih komponenata poruke na 'default' vrednosti.
    // Ako dati string ne sadrzi sve komponente, postavlja njihovu poziciju i duzinu na 0.
    ResetujPozicijeKomponenata();
}

// Vraca 'true' ako data komponenta poruke postoji u formatu.
// ( ako komponenta postoji u formatu, ne znaci da postoji i u telu poruke )
bool KPoruka::PostojiKomponenta( IDKomponentePoruke ID ){
    return format.PostojiKomponenta( ID );
}

// Vraca sadrzaj komponente poruke sa datim ID-om.
string KPoruka::DajKomponentu( IDKomponentePoruke ID ){
    unsigned int nPozicija, nDuzina;

    if ( format.DajPozicijuKomponente( ID, nPozicija, nDuzina ) )
		return sadrzaj.substr( nPozicija, nDuzina );
    else
        return string( "" );
}

// Postavlja vrednost date komponente poruke.
// Vraca 'false' ako data komponenta nije predvidjena formatom poruke.
bool KPoruka::PostaviKomponentu( IDKomponentePoruke ID, string cSadrzajKomponente ) {
    bool izlaz = false;

    if ( format.PostojiKomponenta( ID ) ) {
        // Pronadji poziciju na koju treba ubaciti novu komponentu
        unsigned int nPozicija = 0;
        TOpisPoruke opisPoruke;
        format.DajOpis( opisPoruke );
        TOpisPoruke::iterator o_iter = opisPoruke.begin();
        TOpisPoruke::iterator o_iterEnd = opisPoruke.end();
        // Prodji kroz sve komponente pre ove koja se ubacuje
        while ( o_iter->IDkomponente != ID ){
            nPozicija = o_iter->pozicija + o_iter->duzina;
            o_iter++;
        }
        // Ubaci komponentu u poruku ( zameni staru ako je postojala tj. ako je o_iter->duzina>0 ):
        unsigned int nStaraDuzina = o_iter->duzina;
        unsigned int nNovaDuzina  = cSadrzajKomponente.size();
        unsigned int nIzaKomponente = nPozicija+nStaraDuzina;
//        sadrzaj.replace( nPozicija, nStaraDuzina, cSadrzajKomponente );
// Zbog baga u funkciji replace, koristim obicnu konkatenaciju :
        sadrzaj = sadrzaj.substr( 0, nPozicija ) + 
                  cSadrzajKomponente + 
                  sadrzaj.substr( nIzaKomponente, sadrzaj.length() - nIzaKomponente + 1 );
        format.PostaviPozicijuKomponente( ID, nPozicija, nNovaDuzina );
        // Pomeri pozicije svih komponenata koje se nalaze iza ove koja je sada ubacena
        o_iter++;
        while ( o_iter != o_iterEnd ) {
            if ( !( o_iter->pozicija==0 && o_iter->duzina==0 ) ) // ako komponenta 'postoji'
                o_iter->pozicija += ( nNovaDuzina - nStaraDuzina );
            o_iter++;
        }
        izlaz = true;
    }

    return izlaz;
}

// Postavlja vrednost date komponente poruke na dati bajt ( kopira ga onoliko puta kolika je duzina komponente ).
// Radi samo za komponente cija je duzina poznata ( > 0 ).
// Vraca 'false' ako data komponenta nije predvidjena formatom poruke.
bool KPoruka::PostaviKomponentu( IDKomponentePoruke ID, unsigned char cBajt ){
    bool izlaz = false;

    // Pronadji duzinu komponente
    unsigned int nPozicija, nDuzina;
    if ( KSpisakFormata::Instance()->DefaultPozicijaKomponente( format.DajID(), ID, nPozicija, nDuzina ) ) {
        if ( nDuzina > 0 ) {
            string cPomStr;
            cPomStr.assign( nDuzina, cBajt );
            return PostaviKomponentu( ID, cPomStr );
        }
    }

    return izlaz;
}

// Sracunava 'checksum' poruke. 'Sumira' sve bajtove poruke sem komponente 'SUMA' ( ako postoji ).
// Checksum vraca u obiku stringa tako da moze odmah da se ubaci u poruku.
string KPoruka::IzracunajSumu( void ) {
    unsigned int duzina = sadrzaj.size();
    char suma[2] = {0,0};
    unsigned int nPocetakSume;
    unsigned int nKrajSume;

    // Odredi deo stringa koji sadrzi sumu ( deo koji treba preskociti pri sumiranju )
    unsigned int nPozicija, nDuzina;
    if ( format.DajPozicijuKomponente( KP_SUMA, nPozicija, nDuzina ) ) {
        nPocetakSume = nPozicija;
        nKrajSume = nPocetakSume + nDuzina;
    }
    else    // ako komponenta SUMA ne postoji u poruci, postavi 'neutralne' vrednosti
    {
        nPocetakSume = duzina;
        nKrajSume = 0;
    }

    // Sracunaj sumu
    for ( unsigned int i=0; i<duzina && !( i>=nPocetakSume && i<=nKrajSume ) ; i++ )
        suma[0] = suma[0] ^ sadrzaj[i];

    return string( suma );
}

// Proverava sumu poruke. Vraca 'false' ako suma nije dobra ili ako ne postoji.
bool KPoruka::ProveriSumu( void ){
    return ( DajKomponentu( KP_SUMA ) == IzracunajSumu() );
}

// Postavlja vrednost komponente 'SUMA' tako da odgovara sadrzaju poruke 
// ako komponenta 'SUMA' postoji u poruci.
void KPoruka::PostaviSumu( void ){
    PostaviKomponentu( KP_SUMA, IzracunajSumu() );
}

// Postavlja pozicije i duzine komponenata poruke na 'default' vrednosti.
// Ako je poruka kratka ( ne sadrzi sve komponente ), postavlja njihove pozicije i duzine na 0.
void KPoruka::ResetujPozicijeKomponenata( void ){
    unsigned int nDuzinaPoruke = sadrzaj.size();
    unsigned int nPozicijaKomp;
    unsigned int nDuzinaKomp;
    unsigned int nDuzinaBezSadrzaja;

    TOpisPoruke opisPoruke;
    format.DajOpis( opisPoruke );
    TOpisPoruke::iterator o_iter = opisPoruke.begin();
    TOpisPoruke::iterator o_iterEnd = opisPoruke.end();
    IDKomponentePoruke IDkomponente;

    if ( KSpisakFormata::Instance()->FormatDefault( format ) )
        // Ako se radi o 'default' formatu, pozicija i duzina se setuje na osnovu sadrzaja
        format.PostaviPozicijuKomponente( o_iter->IDkomponente, 0, nDuzinaPoruke );
    else {
        // 1.KORAK : odredi duzine svih komponenata poruke
        IDFormataPoruke formatID = format.DajID();
        nDuzinaBezSadrzaja = 0;
        // 1.a) odredi duzine svih komponenata sem sadrzaja
        while ( o_iter != o_iterEnd ) {
            // Uzmi 'default' poziciju i duzinu komponente poruke
            IDkomponente = o_iter->IDkomponente;
            KSpisakFormata::Instance()->DefaultPozicijaKomponente( formatID, IDkomponente,
                                                                   nPozicijaKomp, nDuzinaKomp );
            if ( nPozicijaKomp + nDuzinaKomp > nDuzinaPoruke && nPozicijaKomp <= nDuzinaPoruke )
                // Ako je samo deo komponente ulazi u sadrzaj, skrati duzinu
                nDuzinaKomp = nDuzinaPoruke - nPozicijaKomp;
            else if ( nPozicijaKomp > nDuzinaPoruke )
                // Ako komponenta ne postoji ( sadrzaj je kratak ), postavi duzinu na 0
                nDuzinaKomp = 0;
            format.PostaviPozicijuKomponente( IDkomponente, 0, nDuzinaKomp );
            if ( IDkomponente != KP_SADRZAJ ) nDuzinaBezSadrzaja += nDuzinaKomp;
            o_iter++;
        }
        // 1.b) ako postoji koponenta 'SADRZAJ', odredi njenu duzinu kao razliku 
        //      duzine poruke i zbira duzina svih komponenata bez sadrzaja
        if ( KSpisakFormata::Instance()->DefaultPozicijaKomponente( formatID, KP_SADRZAJ,
                                                                    nPozicijaKomp, nDuzinaKomp ) )
            format.PostaviPozicijuKomponente( KP_SADRZAJ, 0, nDuzinaPoruke-nDuzinaBezSadrzaja );
        // 2. KORAK : podesi duzine poruka ( da odgovaraju velicinama odredjenim u 1. koraku )
        o_iter = opisPoruke.begin();
        o_iterEnd = opisPoruke.end();
        unsigned int nNovaPozicijaKomp = 0;
        while ( o_iter != o_iterEnd ) {
            IDkomponente = o_iter->IDkomponente;
            // Procitaj duzinu komponente
            format.DajPozicijuKomponente( IDkomponente, nPozicijaKomp, nDuzinaKomp );
            // Postavi novu poziciju komponente
            format.PostaviPozicijuKomponente( IDkomponente, nNovaPozicijaKomp, nDuzinaKomp );
            // Pripremi poziciju sledece komponente
            nNovaPozicijaKomp += nDuzinaKomp;
            o_iter++;
        }
    }
}

// Pomocna procedura : ispisuje sadraj poruke po komponentama na standardni izlaz
void KPoruka::IspisiPoruku( void ) {
    TOpisPoruke opisPoruke;
    format.DajOpis( opisPoruke );
    TOpisPoruke::iterator o_iter = opisPoruke.begin();
    TOpisPoruke::iterator o_iterEnd = opisPoruke.end();
    cout << "Poruka po komponentama :" << endl;
    while ( o_iter != o_iterEnd ) {
        string str = DajKomponentu( o_iter->IDkomponente );
        cout << o_iter->IDkomponente 
             << ": " 
             << KKorisno::Instance()->FormatString( str, FS_BCD_ASCII ) << endl;
        o_iter++;
    }
}
//*********************************** KPoruka << END >> *****************************************

//******************************* TransankcionaPoruka << BEGIN >> *******************************
// Pomocna procedura za konstruktore
void KTransankcionaPoruka::KopirajPoruku( KPoruka* pPoruka ){
    KTransankcionaPoruka::sadrzaj   = pPoruka->Sadrzaj();
    KTransankcionaPoruka::format    = pPoruka->Format();
}

// Konstruktor za formiranje transakcione poruke
KTransankcionaPoruka::KTransankcionaPoruka( string cSadrzajPoruke, KOpisTPoruke opisTP, KFormatPoruke& formatPoruke ){
    auto_ptr<KPoruka> pPoruka( new KPoruka( cSadrzajPoruke, formatPoruke ) );

    KopirajPoruku( pPoruka.get() );
    opisTPoruke.komandaTP      = opisTP.komandaTP;
    opisTPoruke.duzinaTP       = opisTP.duzinaTP;
    opisTPoruke.kodirajSadrzaj = opisTP.kodirajSadrzaj;
}

// Konstruktor za formiranje transakcione poruke
KTransankcionaPoruka::KTransankcionaPoruka( string cSadrzajPoruke, KOpisTPoruke opisTP, IDFormataPoruke formatID ){
    auto_ptr<KPoruka> pPoruka( new KPoruka( cSadrzajPoruke, formatID ) );

    KopirajPoruku( pPoruka.get() );
    opisTPoruke.komandaTP      = opisTP.komandaTP;
    opisTPoruke.duzinaTP       = opisTP.duzinaTP;
    opisTPoruke.kodirajSadrzaj = opisTP.kodirajSadrzaj;
}

// Konstruktor za formiranje 'prazne' poruke datog formata
KTransankcionaPoruka::KTransankcionaPoruka( KOpisTPoruke opisTP, IDFormataPoruke formatID ){
    auto_ptr<KTransankcionaPoruka> pPoruka( new KTransankcionaPoruka( "", opisTP, formatID ) );
    ( *this ) = *pPoruka;
}

// Konstruktor za formiranje poruke koja treba da se salje : zadaje se samo sadrzaj poruke i format.
KTransankcionaPoruka::KTransankcionaPoruka( string cSadrzajPoruke, IDFormataPoruke formatID ){
    auto_ptr<KTransankcionaPoruka> pPoruka( new KTransankcionaPoruka( cSadrzajPoruke, 
                                                                      KOpisTPoruke( KOMANDA_POSALJI, 0, false ), 
                                                                      formatID ) );
    ( *this ) = *pPoruka;
}

// Konstruktor za formiranje poruke koja treba da se primi : zadaje se samo ocekivana duzina i format.
KTransankcionaPoruka::KTransankcionaPoruka( unsigned int nDuzina, IDFormataPoruke formatID ){
    auto_ptr<string> pSadrzaj( new string( "" ) );
    auto_ptr<KTransankcionaPoruka> pPoruka( new KTransankcionaPoruka( *pSadrzaj, 
                                                                      KOpisTPoruke( KOMANDA_POSALJI, nDuzina, false ), 
                                                                      formatID ) );
    ( *this ) = *pPoruka;
}

// Default konstruktor
KTransankcionaPoruka::KTransankcionaPoruka( void ){
    auto_ptr<KTransankcionaPoruka> pPoruka( new KTransankcionaPoruka( "" ) );
    ( *this ) = *pPoruka;
}

// Vraca 'true' ako poruka treba da se posalje na serijski port
bool KTransankcionaPoruka::PorukaZaSlanje( void ) const {
    if ( toupper( opisTPoruke.komandaTP[0] )==KOMANDA_POSALJI[0] ) return true;
    else return false;
};

// Vraca 'true' ako se ocekuje da poruka stigne sa serijskog porta
bool KTransankcionaPoruka::PrijemnaPoruka( void ) const {
    char prvoSlovo = toupper( opisTPoruke.komandaTP[0] );
    if ( prvoSlovo==KOMANDA_PRIMI[0] ) return true;
    else return false;
};

// Postavlja poruku da bude za slanje
void KTransankcionaPoruka::PostaviZaSlanje( void ){ 
    opisTPoruke.komandaTP = KOMANDA_POSALJI;
}

// Postavlja poruku da bude prijemna
void KTransankcionaPoruka::PostaviZaPrijem( void ){ 
    opisTPoruke.komandaTP = KOMANDA_PRIMI;
}

// Vraca duzinu poruke koja treba da se primi sa serijskog porta.
// ( nije isto kao 'Duzina()' u osnovnoj klasi, jer poruka tek treba da se primi, pa 'Duzina()' moze da vrati 0 )
unsigned int KTransankcionaPoruka::DajDuzinuTP( void ) const { 
    return opisTPoruke.duzinaTP;
}

// Postavlja duzinu poruke koja se ocekuje sa serijskog porta.
unsigned int KTransankcionaPoruka::PostaviDuzinuTP( unsigned int duz ){ 
    return ( opisTPoruke.duzinaTP = duz ); 
}

// Ispituje da li se kodira/dekodira sadrzaj poruke ( komponenta poruke KP_SADRZAJ )
bool KTransankcionaPoruka::SadrzajKodiran( void ){
    return opisTPoruke.kodirajSadrzaj;
}
//******************************* TransankcionaPoruka << END >> *******************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -