Cpp speichern und laden von Matrizen mittels Filestream Klasse


Eine Klasse zum Speichern von 4×4 Matrizen z.B: für Kinect Anwendungen. Die Klasse hat eine Kontrolle der gespeicherten Daten, für den Fall, dass etwas schief geht beim Speichern.

header:

#ifndef _MOTION_RECORDER
#define _MOTION_RECORDER
#include <iostream>
#include <fstream>
#include <vector>
#include <gmtl/Matrix.h>
#include <string>

using namespace gmtl;
using namespace std;

class MotionRecorder
{

public:    
    vector<Matrix44f> load(void);
    void record(vector<Matrix44f>);

    string fileNameStr;
    bool recordSession;
    bool loadSession;    
    int motionDataArraySize;
    bool recordFileEOF;

   MotionRecorder(string);
    ~MotionRecorder(void);
    ofstream os;
    ifstream in;
private:    

    void writeAllMotionData(vector<Matrix44f>) ;
    void writeSingleMatrix(gmtl::Matrix44f *motionMatrix, int index);
    vector<Matrix44f> readAllMotionData();
    Matrix44f readSingleMatrix(int index);
    void createEmptyFile(string);

    bool jumpToRightMatrix(int index);
    void skipLines(int lines);
};

#endif

cpp:

#include "MotionRecorder.h"

MotionRecorder::MotionRecorder(string fileNameVar) 
{
    this->fileNameStr = fileNameVar;
    this->recordSession = false;
    this->loadSession = true;
    this->recordFileEOF = false;
    this->motionDataArraySize = 19;
}


MotionRecorder::~MotionRecorder(void)
{
    recordSession = true;
}

void MotionRecorder::record(vector<Matrix44f> frame)
{
    if(!os.is_open())
    {
        os.open(this->fileNameStr, ios::out|ios::binary|ios::app);
        cout  << "RECORDING" << endl << "first run"<< endl;
        createEmptyFile(this->fileNameStr);
        cout << "empty file created"<< endl;
    }
    
    if(!os)
    {    
        cerr << "Fehler beim Öffnen der Recorder Datei: " << this->fileNameStr << endl;
    }
    else
    {        
        writeAllMotionData(frame);
    }
    //os.close();
}

vector<Matrix44f> MotionRecorder::load(void)
{
    if(!in.is_open())
    {
        in.open(this->fileNameStr, ios::in|ios::binary|ios::beg);
         cout << "LOADING" << endl << "first run open"<< endl;
    }
    
    if(!this->recordFileEOF)
    {
        if(!in.is_open())
        {
            cerr << "Fehler beim Öffnen der Recorder Datei: " << this->fileNameStr << endl;
        }
        else
        {    
            return readAllMotionData();
        }
    }
    else
    {
        cout << "Loading from File stopped: Reached the end of recording" <<endl;
        //stream position auf anfang setzen, um erneute wiedergabe zu ermöglichen        
        in.close();
        this->recordFileEOF = false;
        //leerer vektor-> prüfen auf empty möglich
        return vector<Matrix44f>();
    }
}

void MotionRecorder::createEmptyFile(string filename)
{
    fstream f;
    f.open(filename,  ios::out);
    f.close();        
} 



void MotionRecorder::writeAllMotionData(vector<Matrix44f> frame) 
{   
    for(int i = 0; i < frame.size(); i++)
    {
        writeSingleMatrix(&frame[i], i);
    }    
}

void MotionRecorder::writeSingleMatrix(gmtl::Matrix44f *motionMatrix, int index)
{
    float fVal = 0;
    os.write((char*)&index, sizeof (int));
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            fVal = (*motionMatrix)[i][j];
            if(fVal != 0 && fVal != 1)
            {
                //cout << "it works" << endl;
            }
            if(!os.write((char*)&fVal, sizeof (float)))
            {
                cerr << "Fehler beim Schreiben der Recorder Datei!" <<endl;
            }
            else
            {
                cout << fVal;
            }
        }
    }
    os << '\n';
    cout << endl;
}
vector<Matrix44f> MotionRecorder::readAllMotionData()
{
   vector<Matrix44f> returnValue;
   returnValue.clear();

    for(int i = 0; i < motionDataArraySize; i++)
    {
      returnValue.push_back(readSingleMatrix(i));
    }
    return returnValue;
}
Matrix44f MotionRecorder::readSingleMatrix(int index)
{
   Matrix44f returnValue;
   //cout << "read matrix: " << index << endl;
    if(this->jumpToRightMatrix(index))
    {
        float fVal = 0;
        for(int i = 0; i < 4; i++)
        {
            for(int j = 0; j < 4; j++)
            {
            
                if(!in.read((char*)&fVal, sizeof (float)))
                {
                    cerr << "Fehler beim Lesen der aufgenommenen Daten!" <<endl;
                    in.clear();
                    i = 4; j = 4;
                }
                else
                {
                    returnValue[i][j] = fVal;
                    cout << fVal << " ";
                }
                if(fVal != 0 && fVal != 1)
                {
                    //cout << "it works" << endl;
                }
            }
        }
        cout << endl;
        skipLines(1);
    }
    return returnValue;
}

bool MotionRecorder::jumpToRightMatrix(int index)
{
    //cout << "recordFileEOF: " << this->recordFileEOF << endl;
    int checkIndex = -1;
    bool rightMatrixFound = false;
    while(!rightMatrixFound && !this->recordFileEOF)
    {
        in.read((char*)&checkIndex, sizeof (int));
        if(checkIndex != index)
        {
            cout << "found wrong matrix index: " << checkIndex << " expected: " << index << endl;
            if(in.eof())
            {
                cout << "EOF!!!!!!!!!!!!" << endl;    
                in.clear();                
                this->recordFileEOF = true;
            }        
            //jump to right line
            if(checkIndex <= motionDataArraySize)
            {
                int lines = motionDataArraySize - checkIndex + index;
                if(lines >= motionDataArraySize)
                {
                    lines -= motionDataArraySize;
                }
                skipLines(lines);
            }
            else
            {
                skipLines(1);
            }
        }
        else
        {
            rightMatrixFound = true;
        }
        //cout << "searching matrix..."; 
    }
    if(rightMatrixFound)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

void MotionRecorder::skipLines( int lines)
{
    char next;
    for(int i = 0; i < lines; i++)
    { 
        while(in.get(next))
        {
            if (next == '\n') 
            {    
                break;        
            }
        }
    }
}