Forum Sveta kompjutera

Nazad   Forum Sveta kompjutera > Test Run > Programiranje
Uputstvo Članstvo Kalendar Današnje poruke Pretraži

Programiranje Programski jezici, tehnike, alatke...

Odgovor
 
Alatke vezane za temu Vrste prikaza
Stara 19.6.2011, 15:34   #1
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Talking [C++] Binary serialization

Opet mi je bilo dosadno i igrao sam se sa serijalizacijom. Naravno, video sam ovakva rešenja:

Kod:
ofs.write((char*)&obj, sizeof(obj));
U principu je radilo osim ako se unutar objekata nalaze neki pointeri, tada bi samo pisao adresu pointera a ne njegov sadržaj. Zato sam napravio BinarySerializer

BinarySerializer.h
BinarySerializer.cpp
BSTest

Još sam nov sa C++-om tako da je neke stvari možda bilo moguće uraditi na mnogo lakši način. Kako se ovo čudo koristi?

Kod:
BinarySerializer b("filename");

b.serialize();
b << 1 << 2 << "test string";

b.deserialize();
int x, y;
string test;

b >> x >> y >> test;

cout << x << "\n" << y << "\n" << test.c_str();

b.closeFiles();
Ukoliko hoćemo neki objekat da serijalizujemo, možemo ovako:

Kod:
class neka_klasa : public ISerializable
{
public: 
    // blablabla

protected:
    void Serialize(BinarySerializer* b)
    {
        b << x << y << z; // upisujemo potrebne informacije u fajl
    }

    void Deserialize(BinarySerializer* b)
    {
        b >> x >> y >> z; // citamo iz fajla
    }

    // prazan konstruktor je potreban, ako je protected onda mora da se doda i BinarySerializer kao friend
    neka_klasa() { }
    friend class BinarySerializer;
};
Može da se serializuje i std::vector kao što je pokazano u primeru. Verovatno ću se igrati malo da dodam i ostale STL containere
EclipsE je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku EclipsE na korisnoj poruci:
Belphegor (19.6.2011)
Stara 19.6.2011, 21:19   #2
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Interesantna tema i zanimljiv pristup serijalizaciji .
Probao sam malo i skratio ove dve metode:
Kod:
BinarySerializer& BinarySerializer::operator<<(const std::string& str)
{
    unsigned int size = str.size();
    this->addData((char*)&size, sizeof(unsigned int));
    this->addData(str.c_str(), sizeof(char) * size);

    return *this;
}

BinarySerializer& BinarySerializer::operator>>(std::string& str)
{
    unsigned int length;
    this->readData(&length, sizeof(unsigned int));

    /*char* c_str = new char[length + 1];
    this->readData(c_str, sizeof(char) * length);
    c_str[length] = '\0';
    str = c_str;

    delete c_str;*/

    str.reserve(length);
    for(unsigned int i = 0; i < length; ++i)
        str.push_back(ifs.get());

    return *this;
}
mada ova druga malo "odskace" jer ne ide preko readData metode ali opet nigde ne pise da mora.
Ako uradis neke dodatke postavi.
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 19.6.2011, 21:27   #3
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Određen forumom Re: [C++] Binary serialization

Eh, tek sad vidim
Bila je greška u "BinarySerializer& BinarySerializer:: operator<<(const std::string& str)".

U početku sam hteo samo da upišem string tako što ću da idem kroz slova sve do prvog '\0', i da tako zapisem string.

Kod:
for (i = 0; i < size && c[i]; i++);
A lepo sam mogao str.size() da iskoristim i da upišem ceo string
Što se tiče čitanja, ok je samo moraš da proveriš da li je fajl otvoren za deserijalizaciju (ako odradiš b.serialize() i probaš b >> nesto, trebalo bi da baci grešku).

EDIT: sad vidim, u principu i ne mora zato što će this->readData(&length, sizeof(unsigned int)); da se buni ako fajl nije otvoren za deserijalizaciju
EclipsE je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 13:26   #4
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Imam malih promena/poliranja i skidanja dlaka sa jajeta .
Izmenjeno 90% funkcija da budu "const-correct" i zamenjeni C-style cast-ovi u C++ cast-ove. Izmenjeno ime funkcije addData u writeData posto je ova druga readData pa rek'o...

Imao sam samo jedan problem kod jedne funkcije gde sam morao da "skinem" const type clarifier da bi radilo:
Kod:
void BinarySerializer::writeData(const char* ptr, unsigned size) const
{
    assert(mode == 1);

    const_cast<std::ofstream& >(ofs).write(ptr, size);
}
BinarySerialization.h
BinarySerialization.cpp
BSTest.cpp

Mislim da nisam nista prevideo, ako jesam javi.

EDIT: Uuuuups. ima jedan cast previse:
Kod:
void BinarySerializer::readData(char* ptr, unsigned size)
{
    assert(mode == 2);
    
    //ifs.read(reinterpret_cast<char*>(ptr), size);
    ifs.read(ptr, size);
}
Krenuo redom copy/paste i preterao.

Poslednja ispravka: Belphegor (20.6.2011 u 13:44)
Belphegor je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku Belphegor na korisnoj poruci:
EclipsE (20.6.2011)
Stara 20.6.2011, 19:32   #5
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Određen forumom Re: [C++] Binary serialization

Ne znam kako da serializujem map :\

Kada odradim nesto kao:

Kod:
template <typename T, typename Y>
const BinarySerliazer& operator<<(const std::map<T, Y*>& mmap) const
{
    
}
ili čak i:

Kod:
template <typename T>
const BinarySerializer& operator<<(const std::map<T, ISerializable*>& mmap) const
{
}
Ne mogu da pristupim ničemu u mmap
EclipsE je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 19:43   #6
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Mislis ne vidis sve clanove posle access operatora?
I kod mene je zabagovan VS tako da se ne oslanjam mnogo na intellisense.
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 20:08   #7
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Određen forumom Re: [C++] Binary serialization

Ma VS je totalno poludeo
EclipsE je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 20:13   #8
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Ja sam sad nesto probao da kompajliram i napola:
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 20:26   #9
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Određen forumom Re: [C++] Binary serialization

To se i meni desilo
Morao sam da obrišem sve iz /Debug/ i /ipch/ da bi hteo normalno da kompajlira.
EclipsE je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 20:43   #10
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Probao sam sto si rekao ali kod mene ne pomaze.
Napravio sam novi projekat i probao slicno i ne puca kompajler, sad cu da vidim postepeno 'de ga tacno boli.
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 20:44   #11
Sass Drake
V.I.P. Zaštita
 
Član od: 30.9.2007.
Lokacija: Hypnos Control Room, Tokyo Metropolitan Government Building
Poruke: 5.914
Zahvalnice: 1.181
Zahvaljeno 1.320 puta na 1.094 poruka
Određen forumom Re: [C++] Binary serialization

Imate li instalirane sve zakrpe za VS koje su izašle? AKo ne, pravac Windows Update.
Sass Drake je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 20:53   #12
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Ako imas VS probaj kod sebe da ubacis u klasu:
Kod:
template <typename T, typename Y>
const BinarySerliazer& operator << ( const std::map< T, Y* > & mmap ) const
{
}
I kad ne ubacim nista u telo funkcije opet puca, WTF

EDIT:
Nasao sam zasto puca, kopirao sam parce koda od EclipsE-a, pazi na ime tipa koji vraca:
Kod:
template <typename T, typename Y> 
const BinarySerliazer& operator<<(const std::map<T, Y*>& mmap) const 
{      
}
a treba da bude:
Kod:
BinarySerializer
i kompajler se zbunio.

Poslednja ispravka: Belphegor (20.6.2011 u 21:26)
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 20.6.2011, 21:50   #13
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Mislim da je ovo sto se tice std::map kontenera

Kod:
template <typename T, typename Y>
    const BinarySerializer& operator << (const std::map< T, Y* > & mmap) const
    {
        unsigned int size = mmap.size();
        this->writeData(reinterpret_cast<char*>(&size), sizeof(unsigned int));
        std::map<T, Y*>::const_iterator itr = mmap.begin();
        for(; itr != mmap.end(); ++itr)
        {
            this->writeData(reinterpret_cast<const char*>(&(*itr).first), sizeof(T));
            this->writeData(*(*itr).second);
        }
        return *this;
    }

    template <typename T, typename Y>
    BinarySerializer& operator >> (std::map<T, Y*>& mmap)
    {
        unsigned int size;
        this->readData(reinterpret_cast<char*>(&size), sizeof(unsigned int));
        for(unsigned int i = 0; i < size; ++i)
        {
            T key;
            this->readData(reinterpret_cast<char*>(&key), sizeof(T));
            Y* py = new Y();
            *this >> *py;
            mmap[key] = py;
        }
        return *this;
    }
EDIT:
sta ako je key std::string?
Nista onda, se bogu da korisnik ove klase koristi samo primitivne tipove kao key.

Poslednja ispravka: Belphegor (20.6.2011 u 22:06)
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 21.6.2011, 0:03   #14
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Određen forumom Re: [C++] Binary serialization

Ne znam, ne mogu da napravim samo map<std::string, bilosta> :\
A čini mi se kao da sam negde vidjao da koriste std::string za map...

Evo ga nov test.
EclipsE je offline   Odgovor sa citatom ove poruke
Stara 21.6.2011, 5:57   #15
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Jos jedna misao pre nego krenem na posao.
Moze samo da se ubace shift operatori umesto read/writeData i tako ako se ubaci neki "cudni" tip u map dobija se compile time error umesto runtime bug ako nema odgovarajueg overload-a operatora.
Kod:
template <typename T, typename Y>
    const BinarySerializer& operator << (const std::map< T, Y* > & mmap) const
    {
        unsigned int size = mmap.size();
        this->writeData(reinterpret_cast<char*>(&size), sizeof(unsigned int));
        std::map<T, Y*>::const_iterator itr = mmap.begin();
        for(; itr != mmap.end(); ++itr)
        {
            //this->writeData(reinterpret_cast<const char*>(&(*itr).first), sizeof(T));
            *this << (*itr).first;
            this->writeData(*(*itr).second);
        }
        return *this;
    }

    template <typename T, typename Y>
    BinarySerializer& operator >> (std::map<T, Y*>& mmap)
    {
        unsigned int size;
        this->readData(reinterpret_cast<char*>(&size), sizeof(unsigned int));
        for(unsigned int i = 0; i < size; ++i)
        {
            T key;
            //this->readData(reinterpret_cast<char*>(&key), sizeof(T));
            *this >> key;
            Y* py = new Y();
            *this >> *py;
            mmap[key] = py;
        }
        return *this;
    }

Mada bi ja izbacio kontenere iz klase i radio to sa njima van nje i specijalizovao usko za moje potrebe. Jako je tesko napisati genericki kod koji bi resio svaku situaciju.
Belphegor je offline   Odgovor sa citatom ove poruke
Stara 21.6.2011, 12:00   #16
EclipsE
Starosedelac
 
Član od: 16.4.2006.
Lokacija: Scary Movie Reputacija: ■■□
Poruke: 1.337
Zahvalnice: 378
Zahvaljeno 279 puta na 196 poruka
Slanje poruke preko Skypea korisniku EclipsE
Određen forumom Re: [C++] Binary serialization

I size moze da se upise kao:

Kod:
unsigned int size = mmap.size();
*this << size;
Dodah jos jednu funkciju za slucajeve kada Y nije ptr.

Kod:
// <<
    template <typename T, typename Y>
    const BinarySerializer& operator << (const std::map< T, Y* > & mmap) const
    {
        unsigned int size = mmap.size();
        *this << size;

        std::map<T, Y*>::const_iterator itr = mmap.begin();

        for(; itr != mmap.end(); ++itr)
        {
            *this << itr->first;
            *this << *(itr->second);
        }
        return *this;
    }

    template <typename T, typename Y>
    const BinarySerializer& operator << (const std::map< T, Y > & mmap) const
    {
        unsigned int size = mmap.size();
        *this << size;

        std::map<T, Y>::const_iterator itr = mmap.begin();

        for(; itr != mmap.end(); ++itr)
        {
            *this << itr->first;
            *this << itr->second;
        }
        return *this;
    }
Kod:
// >>
    template <typename T, typename Y>
    BinarySerializer& operator >> (std::map<T, Y*>& mmap)
    {
        unsigned int size;
        *this >> size;

        for(unsigned int i = 0; i < size; ++i)
        {
            T key;

            *this >> key;
            Y* py = new Y();
            *this >> *py;
            mmap[key] = py;
        }
        return *this;
    }

    template <typename T, typename Y>
    BinarySerializer& operator >> (std::map<T, Y>& mmap)
    {
        unsigned int size;
        *this >> size;

        for(unsigned int i = 0; i < size; ++i)
        {
            T key;
            Y py;

            *this >> key;
            *this >> py;

            mmap[key] = py;
        }

        return *this;
    }
EclipsE je offline   Odgovor sa citatom ove poruke
Stara 21.6.2011, 17:34   #17
Belphegor
V.I.P. Programiranje
 
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
Određen forumom Re: [C++] Binary serialization

Mozda bi jednu stvar trebalo uzeti u obzir, sto se tice serijalizacije, posto se obicno to radi sa "malim" klasama tipa koje drze neke "atribute", jer sigurno necemo serij. resurse, a s'obzirom da su vec neko vreme u C++ standard ubaceni "Move Semantics, Rvalue References, and Perfect Forwarding" moze da se na dosta mesta izbegne dinamicko alociranje memorije, pogotovu sa malim objektima gde dolazi do fragmentacije memorije i s'tim pogorsavanje performansi, a da i ne spominjem da je pozivanje new/new[] operatora relativno spora operacija u odnosu kreiranja na stack-u a i u isto vreme te stavlja na dilemu koji objekat je odgovoran za alociranje/dealociranje i ostale probleme vezane za memoriju na heap-u, najpametnije je, normalno gde je to moguce, ostaviti alokatorima koji su implementirani u same STL kontenere.
Tako da nema vise potreba za kontenerima koji drze pokazivace, samo je potrebno implementirti odgovarajuce metode u doticne klase - move "copy" konstruktor, move asignment operator...
Ja se tek jos upoznajem sa ovim inovacijama tako da ne bih jos objasnjavao o cemu se tacno radi i kako funkcionise dok to ne savladam 100%, najbolje da odgledas video sa linka koji sam ostavio, ako nisi do sada video, da vidim da li ce da te inspirise za neke nove ideje.
Belphegor je offline   Odgovor sa citatom ove poruke
Sledeći korisnik se zahvaljuje korisniku Belphegor na korisnoj poruci:
EclipsE (26.6.2011)
Odgovor

Bookmarks sajtovi


Vaš status
Ne možete postavljati teme
Ne možete odgovarati na poruke
Ne možete slati priloge uz poruke
Ne možete prepravljati svoje poruke

BB kod: uključeno
Smajliji: uključeno
[IMG] kod: uključeno
HTML kod: isključeno



Sva vremena su po Griniču +2 h. Sada je 22:27.


Powered by vBulletin® verzija 3.8.7
Copyright ©2000–2024, vBulletin Solutions, Inc.
Hosted by Beograd.com