/*************************************** Auteur : Pierre Aubert Mail : aubertp7@gmail.com Licence : CeCILL-C ****************************************/ #include "string_utils.h" #include "backend.h" ///Get the licence in string /** @return licence in string */ std::string ph5_licenceSaveStr(){ std::string body(""); body += "/***************************************\n"; body += "\tAuteur : Pierre Aubert\n"; body += "\tMail : aubertp7@gmail.com\n"; body += "\tLicence : CeCILL-C\n"; body += "****************************************/\n\n\n"; body += "//Warning : this file has been generated automatically by the phoenix_hdf5 program\n"; body += "//Do NOT modify it\n\n\n"; return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeaderSetter(const PTable & table){ std::string body(""); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ std::string type(it->getType()); if(ph5_attributeIsTensor(*it)){ body += "\t\tvoid set" + firstToUpper(it->getName()) + "(size_t i, const "+type+" * tabVal);\n"; }else{ body += "\t\tvoid set" + firstToUpper(it->getName()) + "(size_t i, "+type+" val);\n"; } } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeaderGetter(const PTable & table){ std::string body(""); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ std::string type(it->getType()); if(ph5_attributeIsTensor(*it)){ body += "\t\tconst "+type+" * get" + firstToUpper(it->getName()) + "(size_t i) const;\n"; body += "\t\t"+type+" * get" + firstToUpper(it->getName()) + "(size_t i);\n"; }else{ body += "\t\t"+type+" get" + firstToUpper(it->getName()) + "(size_t i) const;\n"; body += "\t\t"+type+" & get" + firstToUpper(it->getName()) + "(size_t i);\n"; } } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeaderOffset(const PTable & table){ std::string body(""); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\t\tstatic size_t getOffset" + firstToUpper(it->getName()) + "();\n"; } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeaderCompType(const PTable & table){ std::string body("\t\tstatic H5::CompType getCompTypeAll();\n"); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\t\tstatic H5::CompType getCompType" + firstToUpper(it->getName()) + "();\n"; } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeaderDataType(const PTable & table){ std::string body(""); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\t\tstatic H5::DataType getType" + firstToUpper(it->getName()) + "();\n"; } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeaderAttribute(const PTable & table){ std::string body(""); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ if(it->getDocString() != ""){ body += "\t\t///" + it->getDocString() + "\n"; } body += "\t\t"+it->getType()+" * p_"+it->getName()+";\n"; } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableHeader(const PTable & table){ std::string body(""); if(table.getDocString() != ""){ body += "///" + table.getDocString() + "\n"; } std::string name(table.getName()); body += "class " + name + "{\n"; body += "\tpublic:\n"; body += "\t\t" + name + "();\n"; body += "\t\tvirtual ~" + name + "();\n"; body += "\t\tvoid resize(size_t nbRow);\n"; body += "\t\tvoid clear();\n\n"; body += "\t\tvoid read(const H5::H5File & file);\n"; body += "\t\tvoid read(const H5::Group & group);\n\n"; body += "\t\tvoid write(H5::H5File & file) const;\n"; body += "\t\tvoid write(H5::Group & group) const;\n\n"; body += ph5_backendTableHeaderSetter(table); body += ph5_backendTableHeaderGetter(table); body += "\n"; body += ph5_backendTableHeaderOffset(table); body += ph5_backendTableHeaderCompType(table); body += ph5_backendTableHeaderDataType(table); body += "\tprivate:\n"; body += "\t\tvoid readDataSet(const H5::DataSet & dataset);\n"; body += "\t\tvoid writeDataSet(H5::DataSet & dataset) const;\n"; body += "\t\tvoid allocate(size_t nbRow);\n"; body += "\t\t///Number of rows in the table "+name+"\n"; body += "\t\tsize_t p_nbRow;\n"; body += ph5_backendTableHeaderAttribute(table); body += "};\n\n"; return body; } ///Save the header of the given PSource /** @param source : PSource to be used * @return corresponding string */ std::string ph5_backendHeader(const PSource & source){ std::string body(ph5_licenceSaveStr()); std::string baseMacro("__" + strToUpper(eraseExtension(source.getName())) + "_H__"); body += "#ifndef " + baseMacro + "\n"; body += "#define " + baseMacro + "\n\n"; body += "#include \"H5Cpp.h\"\n\n"; const PVecTable & vecTable = source.getVecTable(); for(PVecTable::const_iterator it(vecTable.begin()); it != vecTable.end(); ++it){ body += ph5_backendTableHeader(*it); } body += "#endif\n\n"; return body; } ///Save the source of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceResize(const PTable & table){ std::string body(""), name(table.getName()); body += "///Resize the table " + name + "\n"; body += "/*\t@param nbRow : new number of rows of the Table\n"; body += "*/\n"; body += "void " + name + "::resize(size_t nbRow){\n"; body += "\tif(nbRow == p_nbRow){return;} //Nothing to do\n"; body += "\tclear()\n"; body += "\tallocate(nbRow);\n"; body += "}\n\n"; return body; } ///Save the source of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceClear(const PTable & table){ std::string body(""), name(table.getName()); body += "///Clear the table " + name + " (delete all column)\n"; body += "void " + name + "::clear(){\n"; const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\tif(p_"+it->getName()+" != NULL){delete [] p_"+it->getName()+";p_"+it->getName()+" = NULL;}\n"; } body += "}\n\n"; return body; } ///Save the source of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceRead(const PTable & table){ std::string body(""), name(table.getName()); body += "///Read the table " + name + " from given file\n"; body += "/**\t@param file : HDF5 file to be used\n"; body += "*/\n"; body += "void " + name + "::read(const H5::H5File & file){\n"; body += "\tH5::DataSet dataset = file.openDataSet(\""+table.getDataSetName()+"\");\n"; body += "\treadDataSet(dataset);\n"; body += "}\n\n"; body += "///Read the table " + name + " from given group\n"; body += "/**\t@param group : HDF5 group to be used\n"; body += "*/\n"; body += "void " + name + "::read(const H5::Group & group){\n"; body += "\tH5::DataSet dataset = group.openDataSet(\""+table.getDataSetName()+"\");\n"; body += "\treadDataSet(dataset);\n"; body += "}\n\n"; return body; } ///Save the source of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceWrite(const PTable & table){ std::string body(""), name(table.getName()); body += "///Create and write the table " + name + " in given file\n"; body += "/**\t@param file : HDF5 file to be used\n"; body += "*/\n"; body += "void " + name + "::write(const H5::H5File & file) const{\n"; body += "\thsize_t dim[1];\n"; body += "\tdim[0] = p_nbRow;\n"; body += "\tH5::DataSpace space(1, dim);\n"; body += "\tH5::DataSet dataset = file.createDataSet(\""+table.getDataSetName()+"\", " + name + "::getCompTypeAll(), space);\n"; body += "\twriteDataSet(dataset);\n"; body += "}\n\n"; body += "///Create and write the table " + name + " in given file\n"; body += "/**\t@param group : HDF5 group to be used\n"; body += "*/\n"; body += "void " + name + "::write(const H5::Group & group) const{\n"; body += "\thsize_t dim[1];\n"; body += "\tdim[0] = p_nbRow;\n"; body += "\tH5::DataSpace space(1, dim);\n"; body += "\tH5::DataSet dataset = group.createDataSet(\""+table.getDataSetName()+"\", " + name + "::getCompTypeAll(), space);\n"; body += "\twriteDataSet(dataset);\n"; body += "}\n\n"; return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceSetter(const PTable & table){ std::string body(""), name(table.getName()); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ std::string type(it->getType()); body += "///Set the attribute "+it->getName()+" (column "+it->getColName()+")\n"; if(ph5_attributeIsTensor(*it)){ body += "/**\t@param i : index of the row to be used\n"; body += " * \t@param tabVal : table of value to be copied\n"; body += "*/\n"; body += "void " + name + "::set" + firstToUpper(it->getName()) + "(size_t i, const "+type+" * tabVal){\n"; body += "\tsize_t sizeRow("+ph5_getFullAttributeElement(*it)+");\n"; body += "\tmemcpy(p_"+it->getName()+" + i*sizeRow, tabVal, sizeRow);\n"; body += "}\n\n"; }else{ body += "/**\t@param i : index of the row to be used\n"; body += " * \t@param val : value to be copied\n"; body += "*/\n"; body += "void " + name + "::set" + firstToUpper(it->getName()) + "(size_t i, "+type+" val){\n"; body += "\tp_"+it->getName()+"[i] = val;\n"; body += "}\n\n"; } } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceGetter(const PTable & table){ std::string body(""), name(table.getName()); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ std::string type(it->getType()); if(ph5_attributeIsTensor(*it)){ std::string docString(""); docString += "///Get the tensor i of the attribute "+it->getName()+" (column "+it->getColName()+")\n"; docString += "/**\t@param i : index of the row to be used\n"; docString += " * \t@return pointer to the corresponding tensor\n"; docString += "*/\n"; body += docString; std::string sizeElement(ph5_getFullAttributeElement(*it)); body += "const "+type+" * " + name + "::get" + firstToUpper(it->getName()) + "(size_t i) const{\n"; body += "return p_"+it->getName()+" + i*"+sizeElement+";\n"; body += "}\n\n"; body += docString; body += type+" * " + name + "::get" + firstToUpper(it->getName()) + "(size_t i){\n"; body += "return p_"+it->getName()+" + i**"+sizeElement+";\n"; body += "}\n\n"; }else{ std::string docString(""); docString += "///Get the value i of the attribute "+it->getName()+" (column "+it->getColName()+")\n"; docString += "/**\t@param i : index of the row to be used\n"; docString += " * \t@return corresponding value\n"; docString += "*/\n"; body += docString; body += type+" " + name + "::get" + firstToUpper(it->getName()) + "(size_t i) const{\n"; body += "\treturn p_"+it->getName()+"[i];\n"; body += "}\n\n"; body += docString; body += type+" & " + name + "::get" + firstToUpper(it->getName()) + "(size_t i){\n"; body += "\treturn p_"+it->getName()+"[i];\n"; body += "}\n\n"; } } return body; } ///Get the size of a column /** @param attr : PAttribute to be used * @return corresponding string */ std::string ph5_getSizeOfCol(const PAttribute & attr){ std::string body("sizeof("+attr.getType()+")"); const PVecDim & vecDim = attr.getVecDim(); for(PVecDim::const_iterator it(vecDim.begin()); it != vecDim.end(); ++it){ body += "*" + ph5_dimentionToStr(*it); } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceOffset(const PTable & table){ std::string body(""), name(table.getName()), prevAttribute(""), prevAttributeSize(""); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "///Get the offset of the attribute " + it->getName() + "\n"; body += "/**\t@return offset of the attribute in bytes\n"; body += "*/\n"; body += "size_t " + name + "::getOffset" + firstToUpper(it->getName()) + "(){\n" ; if(prevAttribute == "" && prevAttributeSize == ""){ body += "\treturn 0lu;\n"; }else{ body += "\treturn " + name + "::getOffset" + firstToUpper(prevAttribute) + "() + " + prevAttributeSize + ";\n"; } body += "}\n\n"; prevAttribute = it->getName(); prevAttributeSize = ph5_getSizeOfCol(*it); } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceCompType(const PTable & table){ std::string body(""), name(table.getName()); const PVecAttribute & vecAttriute = table.getVecAttribute(); body += "H5::CompType "+name+"::getCompTypeAll(){\n"; body += "\tsize_t sizeAll("; bool addPlus(false); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ if(addPlus){body += " + ";} body += ph5_getSizeOfCol(*it); addPlus = true; } body += ");\n"; body += "\tH5::CompType typeCol(sizeAll);\n"; for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\ttypeCol.insertMember(\""+it->getColName()+"\", " + name + "::getOffset" + firstToUpper(it->getName()) + "(), "+ name+"::getType" + firstToUpper(it->getName()) + "());\n"; } body += "\treturn typeCol;\n"; body += "}\n\n"; for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "///Get DataType of attribute "+it->getName() +" (column " + it->getColName() + ")\n"; body += "/**\t@return DataType of the attribute "+it->getName() +"\n"; body += "*/\n"; body += "H5::CompType "+name+"::getCompType" + firstToUpper(it->getName()) + "(){\n"; body += "\tH5::CompType typeCol("+ph5_getSizeOfCol(*it)+");\n"; body += "\tdatasetTypeX.insertMember(\""+it->getColName()+"\", 0, "+name+"::getType" + firstToUpper(it->getName()) + "());\n"; body += "\treturn typeCol;\n"; body += "}\n\n"; } return body; } ///Convert a C type into an HDF5 type /** @param type : C type to be converted * @return HDF5 type */ std::string ph5_cTypeToHDF5(const std::string & type){ if(type == "char"){return "H5::PredType::NATIVE_INT8";} else if(type == "unsinged char"){return "H5::PredType::NATIVE_UINT8";} else if(type == "short"){return "H5::PredType::NATIVE_INT16";} else if(type == "unsigned short"){return "H5::PredType::NATIVE_UINT16";} else if(type == "int"){return "H5::PredType::NATIVE_INT";} else if(type == "unsigned int"){return "H5::PredType::NATIVE_UINT";} else if(type == "float"){return "H5::PredType::NATIVE_FLOAT";} else if(type == "double"){return "H5::PredType::NATIVE_DOUBLE";} return ""; } ///Get the corresponding HDF5 type of the given PAttribute /** @param attr : PAttribute to be used * @return corresponding HDF5 type */ std::string ph5_getTypeHDF5(const PAttribute & attr){ std::string body(""); if(ph5_attributeIsTensor(attr)){ const PVecDim & vecDim = attr.getVecDim(); body += "\thsize_t dims["+convertToString(vecDim.size())+"];\n"; size_t i(0lu); for(PVecDim::const_iterator it(vecDim.begin()); it != vecDim.end(); ++it){ body += "\tdims["+convertToString(i)+"] = "+ ph5_dimentionToStr(*it) +";\n"; } body += "\tH5::ArrayType arrayType("+ph5_cTypeToHDF5(attr.getType())+", "+convertToString(vecDim.size())+", dims);\n"; body += "\treturn arrayType;\n"; }else{ body += "\treturn " + ph5_cTypeToHDF5(attr.getType()) + ";\n"; } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceDataType(const PTable & table){ std::string body(""), name(table.getName()); const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "///Get DataType of attribute "+it->getName() +" (column " + it->getColName() + ")\n"; body += "/**\t@return DataType of the attribute "+it->getName() +"\n"; body += "*/\n"; body += "H5::DataType "+name+"::getType" + firstToUpper(it->getName()) + "(){\n"; body += ph5_getTypeHDF5(*it); body += "}\n\n"; } return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceReadDataSet(const PTable & table){ std::string body(""), name(table.getName()); body += "///Read the given DataSet and fill the Table with it\n"; body += "/**\t@param dataset : dataset to be used\n"; body += "*/\n"; body += "void "+name+"::readDataSet(const H5::DataSet & dataset){\n"; body += "\tH5::DataSpace dataSpace = dataset.getSpace();\n"; body += "\tsize_t nbEntries(dataSpace.getSimpleExtentNpoints());\n"; body += "\tresize(nbEntries);\n"; const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\tdataset.read(p_"+it->getName()+", "+name+"::getCompType" + firstToUpper(it->getName()) + "());\n"; } body += "}\n\n"; return body; } ///Save the header of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceWriteDataSet(const PTable & table){ std::string body(""), name(table.getName()); body += "///Write the given DataSet and fill the Table with it\n"; body += "/**\t@param[out] dataset : dataset to be modified\n"; body += "*/\n"; body += "void "+name+"::writeDataSet(H5::DataSet & dataset) const{\n"; const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\tdataset.write(p_"+it->getName()+", "+name+"::getCompType" + firstToUpper(it->getName()) + "());\n"; } body += "}\n\n"; return body; } ///Save the source of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSourceAllocate(const PTable & table){ std::string body(""), name(table.getName()); body += "///Allocate the table " + name + " (delete all column)\n"; body += "/*\t@param nbRow : new number of rows of the Table\n"; body += "*/\n"; body += "void " + name + "::allocate(size_t nbRow){\n"; body += "\tp_nbRow = nbRow;\n"; const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\tp_"+it->getName()+" = new "+it->getType()+"[p_nbRow];\n"; } body += "}\n\n"; return body; } ///Save the source of the given PTable /** @param table : PTable to be used * @return corresponding string */ std::string ph5_backendTableSource(const PTable & table){ std::string body(""), name(table.getName()); body += "///Constructor of the class " + name + "\n"; body += name + "::" + name + "(){\n"; body += "\tp_nbRow = 0lu;\n"; const PVecAttribute & vecAttriute = table.getVecAttribute(); for(PVecAttribute::const_iterator it(vecAttriute.begin()); it != vecAttriute.end(); ++it){ body += "\tp_"+it->getName()+" = NULL;\n"; } body += "}\n\n"; body += "///Destructor of the class " + name + "\n"; body += name + "::~" + name + "(){\n"; body += "\tclear();\n"; body += "}\n\n"; body += ph5_backendTableSourceResize(table); body += ph5_backendTableSourceClear(table); body += ph5_backendTableSourceRead(table); body += ph5_backendTableSourceWrite(table); body += ph5_backendTableSourceSetter(table); body += ph5_backendTableSourceGetter(table); body += ph5_backendTableSourceOffset(table); body += ph5_backendTableSourceCompType(table); body += ph5_backendTableSourceDataType(table); body += ph5_backendTableSourceReadDataSet(table); body += ph5_backendTableSourceWriteDataSet(table); body += ph5_backendTableSourceAllocate(table); return body; } ///Save the source of the given PSource /** @param source : PSource to be used * @return corresponding string */ std::string ph5_backendSource(const PSource & source){ std::string body(ph5_licenceSaveStr()); body += "#include \n"; body += "#include \""+eraseExtension(source.getName())+".h\"\n\n"; const PVecTable & vecTable = source.getVecTable(); for(PVecTable::const_iterator it(vecTable.begin()); it != vecTable.end(); ++it){ body += ph5_backendTableSource(*it); } return body; } ///Save a vector of PSource in the output directory /** @param source : source to be saved * @param outputDir : output directory where to save PSource * @return true on success, false otherwise */ bool ph5_backend(const PSource & source, const std::string & outputDir){ std::string headerSrc(ph5_backendHeader(source)); std::string sourceSrc(ph5_backendSource(source)); std::string baseFileName(eraseExtension(source.getName())); std::string outputHeaderFile(outputDir + "/" + baseFileName + ".h"); std::string outputSourceFile(outputDir + "/" + baseFileName + ".cpp"); if(!saveFileContent(outputHeaderFile, headerSrc)){ std::cerr << "ph5_backend : cannot save header file '"<