degate  0.1.2
ProjectExporter.cc
Go to the documentation of this file.
00001 /*
00002 
00003   This file is part of the IC reverse engineering tool degate.
00004 
00005   Copyright 2008, 2009, 2010 by Martin Schobert
00006 
00007   Degate is free software: you can redistribute it and/or modify
00008   it under the terms of the GNU General Public License as published by
00009   the Free Software Foundation, either version 3 of the License, or
00010   any later version.
00011 
00012   Degate is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015   GNU General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License
00018   along with degate. If not, see <http://www.gnu.org/licenses/>.
00019 
00020 */
00021 
00022 #include <globals.h>
00023 #include <Layer.h>
00024 #include <ProjectExporter.h>
00025 #include <FileSystem.h>
00026 #include <ObjectIDRewriter.h>
00027 #include <LogicModelExporter.h>
00028 #include <GateLibraryExporter.h>
00029 #include <RCVBlacklistExporter.h>
00030 
00031 #include <sys/types.h>
00032 #include <sys/stat.h>
00033 #include <unistd.h>
00034 #include <errno.h>
00035 
00036 #include <string>
00037 #include <iostream>
00038 #include <sstream>
00039 #include <stdexcept>
00040 #include <list>
00041 #include <memory>
00042 #include <boost/foreach.hpp>
00043 
00044 using namespace std;
00045 using namespace degate;
00046 
00047 void ProjectExporter::export_all(std::string const& project_directory, Project_shptr prj,
00048                                  bool enable_oid_rewrite,
00049                                  std::string const& project_file,
00050                                  std::string const& lmodel_file,
00051                                  std::string const& gatelib_file,
00052                                  std::string const& rcbl_file) {
00053 
00054   if(!is_directory(project_directory)) {
00055     throw InvalidPathException("The path where the project should be exported to is not a directory.");
00056   }
00057   else {
00058     ObjectIDRewriter_shptr oid_rewriter(new ObjectIDRewriter(enable_oid_rewrite));
00059 
00060     export_data(join_pathes(project_directory, project_file), prj);
00061 
00062     LogicModel_shptr lmodel = prj->get_logic_model();
00063 
00064     if(lmodel != NULL) {
00065       LogicModelExporter lm_exporter(oid_rewriter);
00066       string lm_filename(join_pathes(project_directory, lmodel_file));
00067       lm_exporter.export_data(lm_filename, lmodel);
00068 
00069 
00070       RCVBlacklistExporter rcv_exporter(oid_rewriter);
00071       rcv_exporter.export_data(join_pathes(project_directory, rcbl_file), prj->get_rcv_blacklist());
00072 
00073       GateLibrary_shptr glib = lmodel->get_gate_library();
00074       if(glib != NULL) {
00075 
00076         GateLibraryExporter gl_exporter(oid_rewriter);
00077         gl_exporter.export_data(join_pathes(project_directory, gatelib_file), glib);
00078       }
00079     }
00080   }
00081 }
00082 
00083 void ProjectExporter::export_data(std::string const& filename, Project_shptr prj) {
00084 
00085   if(prj == NULL) throw InvalidPointerException("Project pointer is NULL.");
00086 
00087   try {
00088 
00089     xmlpp::Document doc;
00090 
00091     xmlpp::Element * root_elem = doc.create_root_node("project");
00092     assert(root_elem != NULL);
00093     set_project_node_attributes(root_elem, prj);
00094 
00095     add_layers(root_elem, prj->get_logic_model(), prj->get_project_directory());
00096     add_grids(root_elem, prj);
00097     add_colors(root_elem, prj);
00098     add_port_colors(root_elem, prj->get_port_color_manager());
00099 
00100     doc.write_to_file_formatted(filename, "ISO-8859-1");
00101 
00102   }
00103   catch(const std::exception& ex) {
00104     std::cout << "Exception caught: " << ex.what() << std::endl;
00105     throw;
00106   }
00107 
00108 }
00109 
00110 void ProjectExporter::add_grids(xmlpp::Element* prj_elem, Project_shptr prj) {
00111 
00112   xmlpp::Element* grids_elem = prj_elem->add_child("grids");
00113   if(grids_elem == NULL) throw(std::runtime_error("Failed to create node."));
00114 
00115 
00116   add_regular_grid(grids_elem, prj->get_regular_horizontal_grid(), "horizontal");
00117   add_regular_grid(grids_elem, prj->get_regular_vertical_grid(), "vertical");
00118 
00119   add_irregular_grid(grids_elem, prj->get_irregular_horizontal_grid(), "horizontal");
00120   add_irregular_grid(grids_elem, prj->get_irregular_vertical_grid(), "vertical");
00121 }
00122 
00123 void ProjectExporter::add_regular_grid(xmlpp::Element* grids_elem,
00124                                        const RegularGrid_shptr grid,
00125                                        std::string const & grid_orientation) {
00126 
00127   xmlpp::Element* grid_elem = grids_elem->add_child("regular-grid");
00128   if(grid_elem == NULL) throw(std::runtime_error("Failed to create node."));
00129 
00130   grid_elem->set_attribute("enabled", grid->is_enabled() ? "true" : "false");
00131   grid_elem->set_attribute("distance", number_to_string<double>(grid->get_distance()));
00132   grid_elem->set_attribute("offset", number_to_string<int>(grid->get_min()));
00133   grid_elem->set_attribute("orientation", grid_orientation);
00134 
00135 
00136 }
00137 
00138 void ProjectExporter::add_irregular_grid(xmlpp::Element* grids_elem,
00139                                          const IrregularGrid_shptr grid,
00140                                          std::string const & grid_orientation) {
00141 
00142   xmlpp::Element* grid_elem = grids_elem->add_child("irregular-grid");
00143   if(grid_elem == NULL) throw(std::runtime_error("Failed to create node."));
00144 
00145   grid_elem->set_attribute("enabled", grid->is_enabled() ? "true" : "false");
00146   grid_elem->set_attribute("orientation", grid_orientation);
00147 
00148   xmlpp::Element* offsets_elem = grid_elem->add_child("offsets");
00149   if(offsets_elem == NULL) throw(std::runtime_error("Failed to create node."));
00150 
00151   for(IrregularGrid::grid_iter iter = grid->begin();
00152       iter != grid->end(); ++iter) {
00153 
00154     xmlpp::Element* offset_elem = offsets_elem->add_child("offset-entry");
00155     if(offset_elem == NULL) throw(std::runtime_error("Failed to create node."));
00156 
00157     offset_elem->set_attribute("offset", number_to_string<int>(*iter));
00158   }
00159 
00160 }
00161 
00162 
00163 void ProjectExporter::set_project_node_attributes(xmlpp::Element* prj_elem,
00164                                                   Project_shptr prj) {
00165 
00166   prj_elem->set_attribute("degate-version", prj->get_degate_version());
00167   prj_elem->set_attribute("name", prj->get_name());
00168   prj_elem->set_attribute("description", prj->get_description());
00169   prj_elem->set_attribute("width", number_to_string<int>(prj->get_width()));
00170   prj_elem->set_attribute("height", number_to_string<int>(prj->get_height()));
00171 
00172   prj_elem->set_attribute("lambda", number_to_string<length_t>(prj->get_lambda()));
00173   prj_elem->set_attribute("pin-diameter", number_to_string<length_t>(prj->get_default_pin_diameter()));
00174   prj_elem->set_attribute("wire-diameter", number_to_string<length_t>(prj->get_default_wire_diameter()));
00175   prj_elem->set_attribute("port-diameter", number_to_string<length_t>(prj->get_default_port_diameter()));
00176 
00177   prj_elem->set_attribute("pixel-per-um", number_to_string<double>(prj->get_pixel_per_um()));
00178   prj_elem->set_attribute("template-dimension", number_to_string<int>(prj->get_template_dimension()));
00179   prj_elem->set_attribute("font-size", number_to_string<unsigned int>(prj->get_font_size()));
00180 
00181   prj_elem->set_attribute("server-url", prj->get_server_url());
00182   prj_elem->set_attribute("last-pulled-transaction-id",
00183                           number_to_string<transaction_id_t>(prj->get_last_pulled_tid()));
00184 }
00185 
00186 
00187 void ProjectExporter::add_layers(xmlpp::Element* prj_elem,
00188                                  LogicModel_shptr lmodel,
00189                                  std::string const& project_dir) {
00190 
00191   if(lmodel == NULL) throw InvalidPointerException();
00192 
00193   xmlpp::Element* layers_elem = prj_elem->add_child("layers");
00194   if(layers_elem == NULL) throw(std::runtime_error("Failed to create node."));
00195 
00196   for(LogicModel::layer_collection::iterator layer_iter = lmodel->layers_begin();
00197       layer_iter != lmodel->layers_end(); ++layer_iter) {
00198 
00199     xmlpp::Element* layer_elem = layers_elem->add_child("layer");
00200     if(layer_elem == NULL) throw(std::runtime_error("Failed to create node."));
00201 
00202     Layer_shptr layer = *layer_iter;
00203     assert(layer->has_valid_layer_id());
00204 
00205     layer_elem->set_attribute("position", number_to_string<layer_position_t>(layer->get_layer_pos()));
00206     layer_elem->set_attribute("id", number_to_string<layer_id_t>(layer->get_layer_id()));
00207     layer_elem->set_attribute("type", layer->get_layer_type_as_string());
00208     layer_elem->set_attribute("description", layer->get_description());
00209     layer_elem->set_attribute("enabled", layer->is_enabled() ? "true" : "false");
00210 
00211     if(layer->has_background_image())
00212       layer_elem->set_attribute("image-filename",
00213                                 get_relative_path(layer->get_image_filename(), project_dir));
00214 
00215   }
00216 
00217 }
00218 
00219 
00220 void ProjectExporter::add_port_colors(xmlpp::Element* prj_elem,
00221                                       PortColorManager_shptr port_color_manager) {
00222 
00223   if(port_color_manager == NULL) throw InvalidPointerException();
00224 
00225   xmlpp::Element* port_colors_elem = prj_elem->add_child("port-colors");
00226   if(port_colors_elem == NULL) throw(std::runtime_error("Failed to create node."));
00227 
00228   for(PortColorManager::port_color_collection::iterator iter = port_color_manager->begin();
00229       iter != port_color_manager->end(); ++iter) {
00230 
00231     const std::string port_name = (*iter).first;
00232     const color_t frame_color = port_color_manager->get_frame_color(port_name);
00233     const color_t fill_color = port_color_manager->get_fill_color(port_name);
00234 
00235     xmlpp::Element* color_elem = port_colors_elem->add_child("port-color");
00236     if(color_elem == NULL) throw(std::runtime_error("Failed to create node."));
00237 
00238     color_elem->set_attribute("fill-color", to_color_string(fill_color));
00239     color_elem->set_attribute("frame-color", to_color_string(frame_color));
00240   }
00241 
00242 }
00243 
00244 void ProjectExporter::add_colors(xmlpp::Element* prj_elem, Project_shptr prj) {
00245 
00246   if(prj == NULL) throw InvalidPointerException();
00247 
00248   xmlpp::Element* colors_elem = prj_elem->add_child("default-colors");
00249   if(colors_elem == NULL) throw(std::runtime_error("Failed to create node."));
00250 
00251   default_colors_t default_colors = prj->get_default_colors();
00252   BOOST_FOREACH(default_colors_t::value_type const& p, default_colors) {
00253     xmlpp::Element* color_elem = colors_elem->add_child("color");
00254     if(color_elem == NULL) throw(std::runtime_error("Failed to create node."));
00255 
00256     std::string o;
00257     switch(p.first) {
00258     case DEFAULT_COLOR_WIRE: o = "wire"; break;
00259     case DEFAULT_COLOR_VIA_UP: o = "via-up"; break;
00260     case DEFAULT_COLOR_VIA_DOWN: o = "via-down"; break;
00261     case DEFAULT_COLOR_EMARKER: o = "emarker"; break;
00262     case DEFAULT_COLOR_GRID: o = "grid"; break;
00263     case DEFAULT_COLOR_ANNOTATION: o = "annotation"; break;
00264     case DEFAULT_COLOR_ANNOTATION_FRAME: o = "annotation-frame"; break;
00265     case DEFAULT_COLOR_GATE: o = "gate"; break;
00266     case DEFAULT_COLOR_GATE_FRAME: o = "gate-frame"; break;
00267     case DEFAULT_COLOR_GATE_PORT: o = "gate-port"; break;
00268     case DEFAULT_COLOR_TEXT: o = "text"; break;
00269     default:
00270       throw std::runtime_error("Invalid object type.");
00271     }
00272 
00273     color_elem->set_attribute("object", o);
00274     color_elem->set_attribute("color", to_color_string(p.second));
00275   }
00276 
00277 }