// KURSACH#6 V.01b // Task: bla-bla-bla... #include #include #include #include #include #include #include #include union UniType { int asInt; float asFloat; char asChar; }; typedef enum DataType {INT, FLOAT, CHAR}; struct FieldDscr { int size; int lenght; int offset; DataType type; }; class DataDscr { public: FieldDscr * fieldDscr; int fieldQty; int recSize; public: ////////////////////////////////////////////////////////////////////// DataDscr() { fieldDscr = NULL; fieldQty = 0; recSize = 0; } ////////////////////////////////////////////////////////////////////// void SetFieldQty(int fq) { FieldDscr * newDscr = new FieldDscr[fq]; if (fieldDscr) { if (fq < fieldQty) fieldQty = fq; memccpy(newDscr, fieldDscr, fieldQty, sizeof(FieldDscr)); //??? delete fieldDscr; } fieldQty = fq; fieldDscr = newDscr; } ////////////////////////////////////////////////////////////////////// void SetField(int fn, DataType dt, int ln) { fieldDscr[fn].type = dt; fieldDscr[fn].lenght = ln; switch (dt) { case INT: fieldDscr[fn].size = sizeof(int); break; case FLOAT: fieldDscr[fn].size = sizeof(float); break; case CHAR: fieldDscr[fn].size = sizeof(char); break; } int offs = 0; for (int i = 0; i < fieldQty; i++) { fieldDscr[i].offset = offs; offs += fieldDscr[i].size * fieldDscr[i].lenght; } recSize = offs; } }; class DataStorage { protected: DataDscr * dataDscr; void * data; int currRec; int recQty; public: ////////////////////////////////////////////////////////////////////// DataStorage() { data = NULL; currRec = 0; recQty = 0; } ////////////////////////////////////////////////////////////////////// DataStorage(DataDscr * dd) { DataDscr(); dataDscr = dd; } ////////////////////////////////////////////////////////////////////// ~DataStorage() { if (data) delete (char *) data; } ////////////////////////////////////////////////////////////////////// void SetRecQty(int rq) { void * newData = new char[rq * dataDscr->recSize]; if (data) { if (rq < recQty) recQty = rq; memccpy(newData, data, recQty, dataDscr->recSize); //??? delete (char *) data; } recQty = rq; data = newData; } ////////////////////////////////////////////////////////////////////// int SetCurrRec(int cr) { if (cr < recQty) currRec = cr; return currRec; } ////////////////////////////////////////////////////////////////////// int operator++(int rq) { if ((currRec + 1) < recQty) currRec++; return currRec; } ////////////////////////////////////////////////////////////////////// int operator--(int rq) { if ((currRec - 1) >= 0) currRec--; return currRec; } ////////////////////////////////////////////////////////////////////// void LoadRecords(void * dp, int rq) { memcpy(data, dp, rq * dataDscr->recSize); } ////////////////////////////////////////////////////////////////////// UniType & operator[](int p1) { return * ((UniType *) ((char *) data + dataDscr->recSize*currRec + dataDscr->fieldDscr[p1].offset)); } }; class DataTable { protected: char * fileName; FILE * dataFile; DataDscr * dataDscr; DataStorage * storage; int recQty; public: ////////////////////////////////////////////////////////////////////// DataTable() { fileName = NULL; dataFile = NULL; storage = NULL; } ////////////////////////////////////////////////////////////////////// ~DataTable() { if (storage) delete storage; if (dataDscr) delete dataDscr; } ////////////////////////////////////////////////////////////////////// void Init() { dataDscr = new DataDscr; } ////////////////////////////////////////////////////////////////////// void Open(char * fn) { fileName = fn; dataFile = fopen(fileName, "r"); if (dataFile) { struct stat fileStat; stat(fn, &fileStat); int rqty = int(fileStat.st_size) / dataDscr->recSize; storage = new DataStorage(dataDscr); recQty = rqty; fclose(dataFile); } else recQty = 0; } ////////////////////////////////////////////////////////////////////// void Close() { if (storage) delete storage; fileName = NULL; dataFile = NULL; storage = NULL; } ////////////////////////////////////////////////////////////////////// void Update() { struct stat fileStat; dataFile = fopen(fileName, "r"); stat(fileName, &fileStat); recQty = int(fileStat.st_size) / dataDscr->recSize; storage = new DataStorage(dataDscr); storage->SetRecQty(recQty); char * fimg = new char[dataDscr->recSize * recQty]; fread(fimg, dataDscr->recSize, recQty, dataFile); storage->SetRecQty(recQty); storage->LoadRecords(fimg, recQty); delete fimg; fclose(dataFile); } ////////////////////////////////////////////////////////////////////// void AddRecords(void * nr, int rq = 1) { dataFile = fopen(fileName, "a"); fwrite(nr, dataDscr->recSize, rq, dataFile); fclose(dataFile); recQty += rq; } ////////////////////////////////////////////////////////////////////// DataStorage & operator[] (int p1) { storage->SetCurrRec(p1); return (* storage); } ////////////////////////////////////////////////////////////////////// int GetRecQty() { return recQty; } }; struct TStudent { uint pkey; char surname[32]; char name[16]; char father[16]; uint sex; uint group; }; class StudTable: public DataTable { public: ////////////////////////////////////////////////////////////////////// void Init() { DataTable::Init(); dataDscr->SetFieldQty(6); dataDscr->SetField(0, INT, 1); dataDscr->SetField(1, CHAR, 32); dataDscr->SetField(2, CHAR, 16); dataDscr->SetField(3, CHAR, 16); dataDscr->SetField(4, INT, 1); dataDscr->SetField(5, INT, 1); } ////////////////////////////////////////////////////////////////////// void Print() { printf("PKey: Surname: Name: Father name: Sex: Group:\n"); storage->SetCurrRec(0); for (int i=0; iSetFieldQty(2); dataDscr->SetField(0, INT, 1); dataDscr->SetField(1, CHAR, 32); } ////////////////////////////////////////////////////////////////////// void Print() { printf("PKey: Name:\n"); storage->SetCurrRec(0); for (int i=0; iSetFieldQty(5); dataDscr->SetField(0, INT, 1); dataDscr->SetField(1, INT, 1); dataDscr->SetField(2, INT, 1); dataDscr->SetField(3, INT, 1); dataDscr->SetField(4, INT, 1); } ////////////////////////////////////////////////////////////////////// void Print() { printf("PKey: Mark: Term: fkStudent: fkSubject:\n"); storage->SetCurrRec(0); for (int i=0; i