Forum Sveta kompjutera

Nazad   Forum Sveta kompjutera > Test Run > Programiranje

Programiranje Programski jezici, tehnike, alatke...

Odgovor
 
Alatke vezane za temu Vrste prikaza
Stara 4.1.2010, 14:25   #1
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom IO System

Ovo je mali IO sistem koji služi za pisanje i čitanje iz fajlova. Svodi se na pravljenje IO komponenti izvođenjem iz osnovne klase IOCapable i overridovanjem tri osnovne funkcije: getBinaryData() kada treba upisati podatke u fajl, parseBinaryData() kada su podaci pročitani i trebaju da se obrade, i getID() koja treba da vrati jednobajtni ID broj koji treba da bude različit za svaku komponentu. Onda se pravi instanca IOSystem klase i registruju se željene komponente. IOSystem podržava ::saveToFile() i ::loadFromFile(). Kada se izvrši saveToFile(), IOSystem "pita" svaku komponentu za njene podatke koje treba snimiti u fajl. Kada se pozove loadFromFile(), IOSystem čita podatke iz određenog fajla i pronalazi koji deo fajla pripada kojoj kompoenti, a zatim im prosleđuje njihove podatke da bi ih parseovali. Ovde takođe postoji i klasa ByteDump za ubacivanje bajtova u vektor ("dump") i onda njihov retrieval kao običan niz spreman za pisanje u fajl. Uključuje i klasu ByteWalker koja služi za čitanje bajtova iz niza (pročitaj sledeći bajt, pročitaj sledećih x bajtova, pročitaj bajtove dok ne naiđeš na zero termination itd.). Uključio sam i test.cpp fajl koji prikazuje kako se pravi IO komponenta, kako se registruje, kako se upisuju sve vrste kompleksnih podataka u byte dump i kako se isti podaci čitaju pomoću ByteWalkera. Program ima komentare (doduše na engleskom) pa ne bi bilo problem da se snađete

Sistem može da se koristi kada treba snimiti dosta podataka u jedan fajl. Nije neka filozofija i veoma mi je bio lak za napraviti, ali ako nekom zatreba ovako nešto da ima pri ruci.

Otvoren sam za sve kritike / sugestije.

Kôd u sledećoj poruci.
Geomaster je offline   Odgovor sa citatom ove poruke
Stara 4.1.2010, 14:26   #2
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom Re: IO System

io.h
Kod:
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable : 4018)

#include <vector>
#include <fstream>
 #include <sys/stat.h>


using namespace std;

// Converts data into bytes
char* toBytes(void*);

class IOCapable
{
public:

    // Should put binary data to write to the file and its length into the pointers, while saving.
    virtual void getBinaryData(char**, long*) = 0; 
    
    // Should parse the binary data read from the input file, while loading.
    virtual void parseBinaryData(char*, long) = 0;

    // Should return the unique ID lengthing one byte, identifying data written by this IO capable component.
    virtual char getID() = 0;
};

class ByteDump
{
    vector<char> dump;
public:

    // Default constructor
    ByteDump();

    // Dump a byte, returns the index in the dump.
    int dumpByte(char);

    // Dump an array of bytes, returns the index of first.
    int dumpBytes(char*, long);

    // Set a byte value in the dump, based on the index.
    void setByte(long, char);

    // Inserts a byte at the specific position in the dump.
    void insertByte(long, char);

    // Removes a byte based on the index.
    void removeByte(long);

    // Allocates a new array and puts the dump into it.
    char* getAsArray();

    // Returns the current dump length.
    long getLength();

    // Default destructor
    ~ByteDump();
};

class ByteWalker
{
private:
    long position;
    char* bytes;
    long length;

    bool end;
public:
    // Default no-parameters constructor
    ByteWalker();

    // Constructor which takes a byte array and its length.
    ByteWalker(char*, long);

    // Sets the byte array, takes array and its length.
    void setByteArray(char*, long);

    // Sets the variables pointed by two arguments to byte array and length, respectively.
    void getByteArray(char**, long*);

    // Moves the pointer relatively to left.
    void moveLeft(long);

    // Moves the pointer relatively to right.
    void moveRight(long);

    // Sets the pointer to a specific byte position.
    void goToPosition(long);

    // Gets the next byte.
    char getByte();

    // Gets the next array of bytes.
    char* getBytes(long);

    // Gets the bytes until the next zero-termination.
    char* getBytesUntilZero();

    // Returns the position of the next byte to be read.
    long getSeek();

    // Returns true if the end of array has been reached.
    bool isEnd();

    // Puts the pointer back to the beginning.
    void goBack();

    // Destructor
    ~ByteWalker();
};

class IOSystem
{
private:
    vector<IOCapable*> Components;
public:

    // Default constructor - no parameters
    IOSystem();

    // Adds (registers) an IO capable component. Accepts an IOCapable derived class, returns the index.
    int addIOComponent(IOCapable*);

    // Removes (unregisters) an IO capable component from the array, takes the index, returns nothing.
    void removeIOComponent(int);

    // Saves (or dumps) all the data to the file. Each IOCapable component's getBinaryData() is invoked. Returns
    // true on success, false on fail. Accepts the filename.
    bool saveToFile(char*);

    // Loads all the data from the file. Each IOCapable component's parseBinaryData() is invoked. Returns true on
    // success, false on fail. Accepts the filename.
    bool loadFromFile(char*);

    // Destructor
    ~IOSystem();
};
Geomaster je offline   Odgovor sa citatom ove poruke
Stara 4.1.2010, 14:26   #3
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom Re: IO System

io.cpp
Kod:
#include "io.h"

char* toBytes(void * ptr)
{
    return (char*)ptr;
}

ByteWalker::ByteWalker()
{
    bytes = new char[1];
    length = 1;

    position = 0;
    end = false;
}

ByteWalker::ByteWalker(char* _bytes, long _length)
{
    bytes = _bytes;
    length = _length;

    position = 0;
    end = false;
}

void ByteWalker::setByteArray(char* _bytes, long _length)
{
    bytes = _bytes;
    length = _length;

    position = 0;

    end = false;
}

void ByteWalker::getByteArray(char** _bytes, long* _length)
{
    *_bytes = bytes;
    *_length = length;
}

char* ByteWalker::getBytes(long len)
{
    if (len > length - position) return NULL;
    char *byte = new char [ len ];

    for (int i = position; i < len + position; i++)
    {
        byte[i-position] = bytes[i];
    }

    position += len;

    return byte;
}

void ByteWalker::moveLeft(long amt = 1)
{
    if (amt > position) return;
    position -= amt;

    end = false;
}

void ByteWalker::moveRight(long amt = 1)
{
    if (position + amt >= length) { end = true; return; }
    position += amt;
}

void ByteWalker::goToPosition(long pos)
{
    if (pos < 0 || pos >= length) return;
    position = pos;
    end = false;
}

char ByteWalker::getByte()
{
    if (position > length - 1) { end = true; return 0; }
        
    if (position != length - 1) 
        position++;

    return bytes[position-1];

}

char* ByteWalker::getBytesUntilZero()
{
    long len = 0;
    bool there = false;
    for (int i=position; i < length; i++)
    {
        if (bytes[i] == 0) { there = true; break; }

        len++;
    }

    if (!there) { end = true; return NULL; }

    return getBytes(len+1);
}

bool ByteWalker::isEnd()
{
    return end;
}

long ByteWalker::getSeek()
{
    return position;
}

ByteWalker::~ByteWalker()
{
}

// ********************************************************

ByteDump::ByteDump()
{

}

int ByteDump::dumpByte(char byte)
{
    dump.push_back(byte);
    return dump.size() - 1;
}

int ByteDump::dumpBytes(char* bytes, long length)
{
    int last = dump.size(); // dump.size() - 1 is the last element. When we append a new one, the last element will be current dump.size().

    for (int i=0; i < length; i++)
    {
        dumpByte(bytes[i]);
    }

    return last;
}

void ByteDump::setByte(long idx, char byte)
{
    if (idx < 0 || idx >= dump.size()) return;
    dump[idx] = byte;
}

void ByteDump::insertByte(long idx, char byte)
{
    if (idx < 0 || idx >= dump.size()) return;
    dump.insert(dump.begin() + idx, byte);
}

void ByteDump::removeByte(long idx)
{
    if (idx < 0 || idx >= dump.size()) return;
    dump.erase(dump.begin() + idx);
}

long ByteDump::getLength()
{
    return dump.size();
}

char* ByteDump::getAsArray()
{
    char* arr = new char[getLength()];

    for (int i=0; i < dump.size(); i++)
    {
        arr[i] = dump[i];
    }

    return arr;
}

ByteDump::~ByteDump()
{

}

////////////////////////////////////////////////////////////

IOSystem::IOSystem()
{
    
}

int IOSystem::addIOComponent(IOCapable * component)
{
    Components.push_back(component);
    return Components.size() - 1;
}

void IOSystem::removeIOComponent(int idx)
{
    if (idx < 0 || idx > Components.size() - 1) return;
    Components.erase(Components.begin() + idx);
}

bool IOSystem::saveToFile(char* filename)
{
    fstream File;
    File.open(filename, ios::out | ios::binary);


    if (!File) return false;

    char idx;
    char *data;
    long len = -1;

    for (int i=0; i < Components.size(); i++)
    {
        idx = Components[i]->getID();

        File.write(&idx, 1); // First we write the index of the component - it'll help us when parsing.
        Components[i]->getBinaryData(&data, &len); // Here we ask the component to store the data into variable data and its length to variable len.

        if (len == -1) return false;

        File.write((char*)&len, sizeof(long)); // Here we write the length of the stream in bytes.
        File.write(data, len); // And here we write the data.
    
        delete[] data;
        len = -1;
    }

    File.close();
    return true;
}

bool IOSystem::loadFromFile(char* filename)
{
    long fsize;

    fstream File;
    File.open(filename, ios::in | ios::binary);

    if (!File) return false;

    struct stat results;

    if (stat(filename, &results) == 0) // Getting the file size
        fsize = results.st_size;
    else 
        return false;

    char* bytes = new char[fsize];
    File.get(bytes, fsize); // Retrieving the whole file

    File.close();

    ByteWalker walk(bytes, fsize);

    int passes = 0;
    while (walk.getSeek() < fsize)
    {
        char ID = 0;
        ID = walk.getByte();
        long size;
        long *sizeptr = (long*)(walk.getBytes(sizeof(long)));
        size = *sizeptr;
        delete sizeptr;

        char* iocapdata = walk.getBytes(size);
        for (int i=0; i < Components.size(); i++)
        {
            if (Components[i]->getID() == ID)
                Components[i]->parseBinaryData(iocapdata, size);
        }
        delete[] iocapdata;
        
        passes++;
    }

    delete[] bytes;

    return true;
}

IOSystem::~IOSystem()
{
    Components.clear();
}
Geomaster je offline   Odgovor sa citatom ove poruke
Stara 4.1.2010, 14:27   #4
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom Re: IO System

test.cpp
Kod:
#include "io.h"

// Dummy struct, just showing how to write complex data (see SampleIO::getBinaryData() ).

struct Sample
{
    int a, b, c;
    char x;
    bool y;
};

// We define our sample IO class.

class SampleIO : public IOCapable
{
public:
    void getBinaryData(char**, long*);
    void parseBinaryData(char*, long);
    char getID();
};

// Now implement the code...

void SampleIO::getBinaryData(char** data, long* length)
{
    // First we have to create the data we want to be saved to file.
    // We use ByteDump to do it.
    ByteDump dump;

    // First, let's dump one single byte, just for the record
    dump.dumpByte('D');

    // Now, dump an integer
    int MyInt = 12345;
    dump.dumpBytes((char*)&MyInt, sizeof(int));

    // Let's dump a string!
    dump.dumpBytes("Hello World!", sizeof("Hello World!"));

    // Now let's dump something complex.
    Sample dummy;
    dummy.a = dummy.b = 123;
    dummy.x = 'A';
    dummy.y = true;

    dump.dumpBytes((char*)&dummy, sizeof(Sample));

    // That's it!
    // Now we set those pointers we received...

    *data = dump.getAsArray();
    *length = dump.getLength();
}

char SampleIO::getID()
{
    // Each IO component has to have unique ID, different from zero, lengthing one byte. Let's say this component's ID is 1.
    return 5;
}

void SampleIO::parseBinaryData(char* data, long length)
{
    // Here we have to parse the data loaded from the file. We create a
    // ByteWalker interface.
    ByteWalker walk(data, length);

    // Remember that we dumped first one byte? Let's get it.
    char byte = walk.getByte();

    // 'byte' now contains 'D'.

    // Then, we dumped an integer so we retrieve sizeof(int) bytes.
    char * bytes = walk.getBytes(sizeof(int));
    int MyInt = *((int*)bytes);
    delete[] bytes;

    // MyInt contains 12345.

    // Now we have to retrieve the string. Since we don't know exact length,
    // we'll just get bytes until we find a zero termination.
    char * String = walk.getBytesUntilZero();

    // String now contains "Hello World!".

    delete[] String;

    // Now we'll retrieve a whole struct from the data.
    bytes = walk.getBytes(sizeof(Sample));
    Sample sample = *((Sample*)bytes);
    delete[] bytes;

    // Now sample contains the data we have dumped previously.
    // a = b = 123, x = 'A', boolean = true.

}

int main()
{
    IOSystem *io = new IOSystem();
    SampleIO *sample = new SampleIO();

    // We ask the IOSystem to register a new component, SampleIO.
    io->addIOComponent((IOCapable*)sample);

    // We save the data of all components (in this case only one :) )
    // to an external file. Each components' getBinaryData() is invoked.
    io->saveToFile("test.bin");

    // Now we parse that same file. This time, each components' parseBinaryData() is invoked.
    // is invoked.
    io->loadFromFile("test.bin");

    delete sample;

    return 0;
}

Poslednja ispravka: Geomaster (6.1.2010 u 15:08) Razlog: IOComponent -> IOCapable
Geomaster je offline   Odgovor sa citatom ove poruke
Stara 4.1.2010, 16:43   #5
doctor
Deo inventara foruma
 
Član od: 14.3.2008.
Lokacija: EHCPCGG
Poruke: 12.110
Zahvalnice: 4.319
Zahvaljeno 3.295 puta na 2.274 poruka
Određen forumom Re: IO System

Looks familiar

Pokusao sam da procitam ovo juce... I razumeo tek delic svega
doctor je offline   Odgovor sa citatom ove poruke
Stara 4.1.2010, 16:45   #6
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom Re: IO System

Zašto? Uopšte nije teško za pročitati... Nagledaćeš se ti hard-to-understand kôda, videćeš...
Geomaster je offline   Odgovor sa citatom ove poruke
Stara 4.1.2010, 17:03   #7
doctor
Deo inventara foruma
 
Član od: 14.3.2008.
Lokacija: EHCPCGG
Poruke: 12.110
Zahvalnice: 4.319
Zahvaljeno 3.295 puta na 2.274 poruka
Određen forumom Re: IO System

Cek', rekoh ti, tek sam juce poceo da se zamlacujem iole ozbiljno sa klasama
doctor je offline   Odgovor sa citatom ove poruke
Stara 6.1.2010, 12:59   #8
Stevvan
Veteran
 
Član od: 17.12.2005.
Lokacija: Zarkovo, Beograd
Poruke: 1.114
Zahvalnice: 97
Zahvaljeno 179 puta na 104 poruka
Slanje poruke preko MSN-a korisniku Stevvan Slanje poruke preko Skypea korisniku Stevvan
Određen forumom Re: IO System

Deluje mi kao da bih ovaj kod mogao da upotrebim za nesto Imas 2 greske koje kompajler izbacuje, u io.h umesto boolean treba bool, i u test.cpp umesto IOComponent IOCapable.
Stevvan je offline   Odgovor sa citatom ove poruke
Stara 6.1.2010, 15:08   #9
Geomaster
V.I.P. Programiranje
 
Član od: 28.6.2007.
Lokacija: Beograd
Poruke: 2.342
Zahvalnice: 2.836
Zahvaljeno 1.047 puta na 507 poruka
Slanje poruke preko MSN-a korisniku Geomaster Slanje poruke preko Skypea korisniku Geomaster
Određen forumom Re: IO System

Citat:
Stevvan kaže: Pregled poruke
Deluje mi kao da bih ovaj kod mogao da upotrebim za nesto Imas 2 greske koje kompajler izbacuje, u io.h umesto boolean treba bool, i u test.cpp umesto IOComponent IOCapable.
Ispravljeno, hvala!
Geomaster je offline   Odgovor sa citatom ove poruke
Odgovor

Bookmarks sajtovi

Alatke vezane za temu
Vrste prikaza

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


Slične teme
tema temu započeo forum Odgovora Poslednja poruka
GTA 4 za PC! JJ92 Akcione igre 8690 9.5.2023 18:36
System restore/backup files jonathan Operativni sistemi 7 1.11.2009 17:29
System Restore (zauzeće diska) jonathan Operativni sistemi 10 13.9.2009 14:14
System Restore za neupućene dacajak Operativni sistemi 6 16.2.2009 23:11
Freelancer/tips&tricks BabaRoga Online susreti 70 21.2.2007 19:50


Sva vremena su po Griniču +2 h. Sada je 23:56.


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