/* * Copyright (C) 2006-2008 Dynare Team * * This file is part of Dynare. * * Dynare is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Dynare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Dynare. If not, see . */ /* Usefull documentation: Matlab 7 Mat-File Format ----------------------------------------------- revision: October 2008 PDF only Rereleased for Version 7.7 (Release 2008b) available at: http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf */ #include "MatlabFile.hh" MatlabFile::MatlabFile() { } MatlabFile::~MatlabFile() { } ArrayElem::ArrayElem() { } ArrayElem::~ArrayElem() { } string UTF8::ReadAlph(char* InBuff, int* pBuff, int Size) const { char tmp_c[Size+1]; string str; memcpy(&tmp_c, InBuff+*pBuff, Size); tmp_c[Size]=0; str.assign(tmp_c); if(Size<=4) *pBuff += 4; else if(Size % 8) *pBuff += 8*ceil(double(Size) / 8); else *pBuff += Size; return(str); } string UTF16::ReadAlph(char* InBuff, int* pBuff, int Size) const { string str(""); for(int i=0;isize()) for(unsigned int i=0;isize();i++) { tmpv=ret.Simple->ReadNum(InBuff, pBuff); VNumeric.push_back(tmpv); } //to align pBuff on a 4 Bytes if(*pBuff % 4) *pBuff += 4-(*pBuff % 4); delete ret.Simple; break; case AlphaNumeric: for(unsigned int i=0;isize();i++) Vstr.push_back(ret.Simple->ReadAlph(InBuff, pBuff, data_header.Number_of_Bytes)); //to align pBuff on a 4 Bytes if(*pBuff % 4) *pBuff += 4-(*pBuff % 4); delete ret.Simple; break; case Matrix: array_elem = matrix.ReadArray_class(InBuff, pBuff); array_elem->ReadArray(InBuff, pBuff, flag); break; case Compressed: cerr << "Error: Compressed data in Mat-file not implemnted yet!\n set option -v6 when saving to Mat-file\n"; exit(EXIT_FAILURE); case Unknown: cerr << "Error: Mat-file format use incomptible format with Matlab 7 specification!\n set option -v6 when saving to Mat-file\n"; exit(EXIT_FAILURE); } } returned_ReadData_t SimpleElem::ReadData(char* InBuff, int* pBuff) const { Data_Header_t data_header; data_header = ReadDataHeader(InBuff, pBuff); return(Get_Data_Class(data_header)); } void SimpleElem::Collect(const string &name, bool found, CollectStruct &collect_struct) const { if(VNumeric.size()) { if(found) collect_struct.variable_double_name[collect_struct.tmp_name]=VNumeric; } else if(Vstr.size()) { if(found) collect_struct.variable_string_name[collect_struct.tmp_name]=Vstr; } else { if(array_elem) { array_elem->Collect(name, found, collect_struct); } } } void SimpleElem::Print() const { if(VNumeric.size()) { for(vector::const_iterator it=VNumeric.begin(); it!=VNumeric.end(); it++) cout << " " << *it; } else if(Vstr.size()) { for(vector::const_iterator it=Vstr.begin(); it!=Vstr.end(); it++) cout << " " << *it; } else { if(array_elem) array_elem->Print(); } } void SimpleElem::Delete() const { if(array_elem) { array_elem->Delete(); delete array_elem; } } LongInt ArrayElem::ReadINT32(char* InBuff, int* pBuff) const { LongInt val; memcpy(&val, InBuff+*pBuff, sizeof(val)); *pBuff += sizeof(val); return(val); } Array_Flag_t ArrayElem::ReadArrayFlag(char* InBuff, int* pBuff) /*const*/ { Array_Flag_t array_flag; memcpy(&array_flag, InBuff+*pBuff, sizeof(array_flag)); *pBuff += sizeof(array_flag); array_complex = (bool)(array_flag.flag & 16); array_global = array_flag.flag & 32; array_logical = array_flag.flag & 64; type = (Array_Type)array_flag.classe; if(type==Sparse_array) array_nzmax = array_flag.nzmax; return(array_flag); } void ArrayElem::ReadArrayDimension(char* InBuff, int* pBuff) /*const*/ { Data_Header_t data_header; data_header = ReadDataHeader(InBuff, pBuff); number_of_dimensions = data_header.Number_of_Bytes/4; for(int i=0; iReadDataHeader(InBuff, pBuff); VCell.push_back(simple); simple->DataProceed(data_header, InBuff, pBuff, flag); } } void Structure::Collect(const string &name, bool found, CollectStruct &collect_struct) const { if(name==variable_name || found) { found = true; vector::const_iterator it2=Structure_Elem_name.begin(); for(vector::const_iterator it=VCell.begin(); it!=VCell.end(); it++) { collect_struct.tmp_name = *it2; it2++; (*it)->Collect(name, found, collect_struct); } } } void Structure::Print() const { cout << "Structure: " << variable_name << "\n"; vector::const_iterator it2=Structure_Elem_name.begin(); int i=0; for(vector::const_iterator it=VCell.begin(); it!=VCell.end(); it++) { cout << ++i << " -> " << *it2 << " :"; it2++; (*it)->Print(); cout << "\n"; } } void Structure::Delete() const { vector::const_iterator it2=Structure_Elem_name.begin(); for(vector::const_iterator it=VCell.begin(); it!=VCell.end(); it++) { (*it)->Delete(); delete *it; } } void Structure::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { SimpleElem* simple; int i; ReadArrayDimension(InBuff, pBuff); ReadArrayName(InBuff, pBuff); ReadStructureNames(InBuff, pBuff); flag.no_name=true; for(i=0;iReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); data_header=simple->ReadDataHeader(InBuff, pBuff); VCell.push_back(simple); simple->DataProceed(data_header, InBuff, pBuff, flag); } } void Object::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Object::Print() const { } void Object::Delete() const { } void Object::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { cerr << "Error: Object not implemented\n"; exit(EXIT_FAILURE); } void CharacterArray::Collect(const string &name, bool found, CollectStruct &collect_struct) const { if(name==variable_name || found) { found = true; collect_struct.tmp_name=variable_name; vector::const_iterator it=VCell.begin(); (*it)->Collect(name, found, collect_struct); } } void CharacterArray::Print() const { cout << "CharacterArray: " << variable_name << "\n"; vector::const_iterator it=VCell.begin(); (*it)->Print(); cout << "\n"; } void CharacterArray::Delete() const { //cout << "CharacterArray: " << variable_name << "\n"; vector::const_iterator it=VCell.begin(); (*it)->Delete(); delete *it; //cout << "\n"; } void CharacterArray::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; ReadArrayDimension(InBuff, pBuff); Matrix_Elem_number = 1; for(unsigned int i=0;iReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void SparseArray::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void SparseArray::Print() const { cout << "Sparse Array: " << variable_name << "\n"; } void SparseArray::Delete() const { //cout << "Sparse Array: " << variable_name << "\n"; } void SparseArray::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { cerr << "Error: Sparse Array not implemented\n"; exit(EXIT_FAILURE); } void DoublePrecisionArray::Collect(const string &name, bool found, CollectStruct &collect_struct) const { if(name==variable_name || found) { found = true; collect_struct.tmp_name=variable_name; vector::const_iterator it=VCell.begin(); (*it)->Collect(name, found, collect_struct); } } void DoublePrecisionArray::Print() const { cout << "DoublePrecisionArray: " << variable_name << "\n"; vector::const_iterator it=VCell.begin(); (*it)->Print(); cout << "\n"; } void DoublePrecisionArray::Delete() const { vector::const_iterator it=VCell.begin(); (*it)->Delete(); delete *it; } void DoublePrecisionArray::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; ReadArrayDimension(InBuff, pBuff); Matrix_Elem_number = 1; for(unsigned int i=0;iReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void SinglePrecisionArray::Collect(const string &name, bool found, CollectStruct &collect_struct) const { if(name==variable_name || found) { found = true; collect_struct.tmp_name=variable_name; vector::const_iterator it=VCell.begin(); (*it)->Collect(name, found, collect_struct); } } void SinglePrecisionArray::Print() const { cout << "SinglePrecisionArray: " << variable_name << "\n"; vector::const_iterator it=VCell.begin(); (*it)->Print(); cout << "\n"; } void SinglePrecisionArray::Delete() const { vector::const_iterator it=VCell.begin(); (*it)->Delete(); delete *it; } void SinglePrecisionArray::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; ReadArrayDimension(InBuff, pBuff); Matrix_Elem_number = 1; for(unsigned int i=0;iReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void Bit8SignedInteger::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Bit8SignedInteger::Print() const { //cout << "Bit8SignedInteger: \n"; } void Bit8SignedInteger::Delete() const { //cout << "Bit8SignedInteger: \n"; } void Bit8SignedInteger::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; simple=new SimpleElem; VCell.push_back(simple); data_header=simple->ReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void Bit8UnsignedInteger::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Bit8UnsignedInteger::Print() const { //cout << "Bit8UnsignedInteger: \n"; } void Bit8UnsignedInteger::Delete() const { //cout << "Bit8UnsignedInteger: \n"; } void Bit8UnsignedInteger::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; simple=new SimpleElem; VCell.push_back(simple); data_header=simple->ReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void Bit16SignedInteger::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Bit16SignedInteger::Print() const { //cout << "Bit16SignedInteger: \n"; } void Bit16SignedInteger::Delete() const { //cout << "Bit16SignedInteger: \n"; } void Bit16SignedInteger::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; simple=new SimpleElem; VCell.push_back(simple); data_header=simple->ReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void Bit16UnsignedInteger::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Bit16UnsignedInteger::Print() const { //cout << "Bit16UnsignedInteger: \n"; } void Bit16UnsignedInteger::Delete() const { //cout << "Bit16UnsignedInteger: \n"; } void Bit16UnsignedInteger::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; simple=new SimpleElem; VCell.push_back(simple); data_header=simple->ReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void Bit32SignedInteger::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Bit32SignedInteger::Print() const { //cout << "Bit32SignedInteger: \n"; } void Bit32SignedInteger::Delete() const { //cout << "Bit32SignedInteger: \n"; } void Bit32SignedInteger::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; simple=new SimpleElem; VCell.push_back(simple); data_header=simple->ReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } void Bit32UnsignedInteger::Collect(const string &name, bool found, CollectStruct &collect_struct) const { } void Bit32UnsignedInteger::Print() const { //cout << "Bit32UnsignedInteger: \n"; } void Bit32UnsignedInteger::Delete() const { //cout << "Bit32UnsignedInteger: \n"; } void Bit32UnsignedInteger::ReadArray(char* InBuff, int* pBuff, FlagStructure_t flag) { Data_Header_t data_header; SimpleElem* simple; simple=new SimpleElem; VCell.push_back(simple); data_header=simple->ReadDataHeader(InBuff, pBuff); simple->DataProceed(data_header, InBuff, pBuff, flag); } Data_Header_t MatlabFile::ReadDataHeader(ifstream &MatFile) { Data_Header_t data_header; MatFile.read(reinterpret_cast(&data_header.DataType),sizeof(data_header.DataType)); MatFile.read(reinterpret_cast(&data_header.S_Number_of_Bytes),sizeof(data_header.S_Number_of_Bytes)); if(data_header.S_Number_of_Bytes!=0) data_header.Number_of_Bytes=data_header.S_Number_of_Bytes; else { MatFile.read(reinterpret_cast(&data_header.Number_of_Bytes),sizeof(data_header.Number_of_Bytes)); } if(data_header.Number_of_Bytes<8) data_header.Number_of_Bytes = 8; return(data_header); } void MatlabFile::MatFileRead(string filename) { ifstream MatFile; Data_Header_t data_header; SimpleElem *simpl; int pBuff; FlagStructure_t flag; //ArrayElem elem; MatFile.open(filename.c_str(),std::ios::in | std::ios::binary); if (!MatFile.is_open()) { cerr << filename.c_str() << " Cannot be opened\n"; exit(EXIT_FAILURE); } // Read the Header of the Mat-File MatFile.read(reinterpret_cast(&header),sizeof(header)); do { data_header=ReadDataHeader(MatFile); char* InBuff; InBuff = (char*)malloc(data_header.Number_of_Bytes+1); MatFile.read(InBuff,data_header.Number_of_Bytes+1); pBuff = 0; simpl = new SimpleElem; VSimpl.push_back(simpl); flag.no_name=false; flag.character=false; simpl->DataProceed(data_header, InBuff, &pBuff, flag); free(InBuff); } while(!MatFile.eof()); MatFile.close(); } bool MatlabFile::Collect(const string &name, CollectStruct &collect_struct) const { for(vector::const_iterator it=VSimpl.begin(); it!=VSimpl.end(); it++) (*it)->Collect(name, false, collect_struct); return(!(collect_struct.variable_double_name.empty() and collect_struct.variable_string_name.empty())); } void MatlabFile::MatFilePrint() { for(vector::iterator it=VSimpl.begin(); it!=VSimpl.end(); it++) (*it)->Print(); } void MatlabFile::Delete() { for(vector::iterator it=VSimpl.begin(); it!=VSimpl.end(); it++) { (*it)->Delete(); delete *it; } } /* int main(int argc, char** argv) { CollectStruct collect_struct; MatlabFile matlab_file; matlab_file.MatFileRead("gimf_steady.mat"); //matlab_file.MatFileRead("essai.mat"); matlab_file.MatFilePrint(); bool tmp_b=false; //string tmp_s("stored_values"); tmp_b=matlab_file.Collect("stored_values", collect_struct); if(tmp_b) { int i=0; for(map >::iterator it2=collect_struct.variable_double_name.begin();it2!=collect_struct.variable_double_name.end();it2++) { i++; cout << i << " " << it2->first.c_str() << " : "; for(vector::iterator it=it2->second.begin();it!=it2->second.end();it++) cout << *it; cout << "\n"; } } } */