degate 0.1.1
Gate.cc
Go to the documentation of this file.
00001 /* -*-c++-*-
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 <degate.h>
00023 #include <Gate.h>
00024 
00025 #include <boost/format.hpp>
00026 
00027 using namespace degate;
00028 
00029 Gate::Gate(int _min_x, int _max_x, int _min_y, int _max_y,
00030            ORIENTATION _orientation) :
00031   Rectangle(_min_x, _max_x, _min_y, _max_y),
00032   orientation(_orientation),
00033   template_type_id(0) {
00034 }
00035 
00036 Gate::Gate(BoundingBox const& bounding_box,
00037            ORIENTATION _orientation):
00038   Rectangle(bounding_box.get_min_x(), bounding_box.get_max_x(),
00039             bounding_box.get_min_y(), bounding_box.get_max_y()),
00040   orientation(_orientation),
00041   template_type_id(0) {
00042 }
00043 
00044 Gate::~Gate() {
00045   debug(TM, "destroy gate");
00046   if(gate_template != NULL) remove_template();
00047 }
00048 
00049 void Gate::add_port(GatePort_shptr gate_port) {
00050   if(!gate_port->has_valid_object_id())
00051     throw InvalidObjectIDException("Error in Gate::add_port(). "
00052                                    "The port has no valid object ID.");
00053 
00054   if(!gate_port->has_template_port())
00055     throw DegateLogicException("Error in Gate::add_port(). "
00056                                "The gate port has no template port");
00057 
00058   if(!has_orientation())
00059     throw DegateLogicException("Error in Gate::add_port(). "
00060                                "The gate has no defined orientation");
00061 
00062   gate_port->set_x(get_min_x() +
00063                    get_relative_x_position_within_gate
00064                      (gate_port->get_template_port()->get_x()));
00065   gate_port->set_y(get_min_y() +
00066                    get_relative_y_position_within_gate
00067                      (gate_port->get_template_port()->get_y()));
00068 
00069   gate_ports.insert(gate_port);
00070 }
00071 
00072 
00073 void Gate::remove_port(GatePort_shptr gate_port) {
00074   port_iterator found = gate_ports.find(gate_port);
00075   if(found != gate_ports.end()) {
00076     gate_ports.erase(found);
00077   }
00078   else throw CollectionLookupException();
00079 }
00080 
00081 
00082 GatePort_shptr Gate::get_port_by_template_port(GateTemplatePort_shptr template_port) {
00083   for(port_iterator piter = ports_begin(); piter != ports_end(); ++piter) {
00084     GatePort_shptr gate_port = *piter;
00085     GateTemplatePort_shptr tmpl_port = gate_port->get_template_port();
00086     if(tmpl_port == template_port)
00087       return gate_port;
00088   }
00089   throw CollectionLookupException();
00090 }
00091 
00092 
00093 void Gate::set_template_type_id(object_id_t template_type_id) {
00094   this->template_type_id = template_type_id;
00095 }
00096 
00097 
00098 object_id_t Gate::get_template_type_id() const {
00099   return template_type_id;
00100 }
00101 
00102 
00103 
00104 void Gate::set_gate_template(std::tr1::shared_ptr<GateTemplate> gate_template) {
00105   if(has_template()) {
00106     this->gate_template->decrement_reference_counter();
00107   }
00108 
00109   if(this->gate_template != gate_template) {
00110     this->gate_template = gate_template;
00111     set_template_type_id(gate_template->get_object_id());
00112     set_fill_color(gate_template->get_fill_color());
00113     set_frame_color(gate_template->get_frame_color());
00114     this->gate_template->increment_reference_counter();
00115 
00116     if((unsigned int)get_width() != gate_template->get_width() ||
00117        (unsigned int)get_height() != gate_template->get_height()) {
00118       set_max_x(get_min_x() + gate_template->get_width());
00119       set_max_y(get_min_y() + gate_template->get_height());
00120     }
00121   }
00122 }
00123 
00124 
00125 std::tr1::shared_ptr<GateTemplate> Gate::get_gate_template() const {
00126   return gate_template;
00127 }
00128 
00129 bool Gate::has_template() const {
00130   return gate_template != NULL;
00131 }
00132 
00133 void Gate::remove_template() {
00134   gate_ports.clear();
00135   orientation = ORIENTATION_UNDEFINED;
00136   template_type_id = 0;
00137   set_fill_color(0);
00138   set_frame_color(0);
00139   if(has_template()) {
00140     gate_template->decrement_reference_counter();
00141     gate_template.reset();
00142   }
00143 }
00144 
00145 bool Gate::has_template_port(GateTemplatePort_shptr template_port) const {
00146   for(port_iterator piter = ports_begin(); piter != ports_end(); ++piter) {
00147     GatePort_shptr gate_port = *piter;
00148 
00149     assert(gate_port->get_template_port()->has_valid_object_id());
00150     assert(template_port->has_valid_object_id());
00151 
00152     if(gate_port->get_template_port()->get_object_id() == template_port->get_object_id()) {
00153 
00154       // debugging
00155       if(gate_port->get_template_port() != template_port) {
00156         std::cout << "ERROR\n";
00157         gate_port->print();
00158       }
00159       // debugging
00160       //assert(gate_port->get_template_port() == template_port);
00161 
00162       return true;
00163     }
00164 
00165   }
00166   return false;
00167 }
00168 
00169 
00170 void Gate::set_orientation(ORIENTATION _orientation) {
00171   orientation = _orientation;
00172 }
00173 
00174 Gate::ORIENTATION Gate::get_orientation() const {
00175   return orientation;
00176 }
00177 
00178 bool Gate::has_orientation() const {
00179   return orientation != ORIENTATION_UNDEFINED;
00180 }
00181 
00182 std::string Gate::get_orienation_type_as_string() const {
00183   switch(orientation) {
00184   case ORIENTATION_NORMAL: return std::string("normal");
00185   case ORIENTATION_FLIPPED_UP_DOWN: return std::string("flipped-up-down");
00186   case ORIENTATION_FLIPPED_LEFT_RIGHT: return std::string("flipped-left-right");
00187   case ORIENTATION_FLIPPED_BOTH: return std::string("flipped-both");
00188   case ORIENTATION_UNDEFINED:
00189   default: return std::string("undefined");
00190   }
00191 }
00192 
00193 
00194 Gate::port_iterator Gate::ports_begin() {
00195   return gate_ports.begin();
00196 }
00197 
00198 Gate::port_const_iterator Gate::ports_begin() const {
00199   return gate_ports.begin();
00200 }
00201 
00202 Gate::port_iterator Gate::ports_end() {
00203   return gate_ports.end();
00204 }
00205 
00206 Gate::port_const_iterator Gate::ports_end() const {
00207   return gate_ports.end();
00208 }
00209 
00210 
00211 unsigned int Gate::get_relative_x_position_within_gate(int rel_x) const {
00212   switch(orientation) {
00213   case ORIENTATION_NORMAL:
00214   case ORIENTATION_FLIPPED_UP_DOWN:
00215     return rel_x;
00216   case ORIENTATION_FLIPPED_LEFT_RIGHT:
00217   case ORIENTATION_FLIPPED_BOTH:
00218     return get_width() - rel_x;
00219   case ORIENTATION_UNDEFINED:
00220   default:
00221     assert(orientation != ORIENTATION_UNDEFINED);
00222     throw DegateRuntimeException("Can't calculate a position for an undefined orientation");
00223   }
00224 }
00225 
00226 
00227 unsigned int Gate::get_relative_y_position_within_gate(int rel_y) const {
00228   switch(orientation) {
00229   case ORIENTATION_NORMAL:
00230   case ORIENTATION_FLIPPED_LEFT_RIGHT:
00231     return rel_y;
00232   case ORIENTATION_FLIPPED_UP_DOWN:
00233   case ORIENTATION_FLIPPED_BOTH:
00234     return get_height() - rel_y;
00235   case ORIENTATION_UNDEFINED:
00236   default:
00237     assert(orientation != ORIENTATION_UNDEFINED);
00238     throw DegateRuntimeException("Can't calculate a position for an undefined orientation");
00239   }
00240 }
00241 
00242 
00243 const std::string Gate::get_descriptive_identifier() const {
00244 
00245   if(has_template()) {
00246     if(has_name()) {
00247       boost::format fmter("%1% : %2%");
00248       fmter % get_name() % get_gate_template()->get_name();
00249       return fmter.str();
00250     }
00251     else {
00252       boost::format fmter("%1% (%2%)");
00253       fmter % get_gate_template()->get_name() % get_object_id();
00254       return fmter.str();
00255     }
00256   }
00257   else {
00258     if(!has_name()) {
00259       boost::format fmter("gate (%1%)");
00260       fmter % get_object_id();
00261       return fmter.str();
00262     }
00263     else {
00264       boost::format fmter("gate %1% (%2%)");
00265       fmter % get_name() % get_object_id();
00266       return fmter.str();
00267     }
00268   }
00269 
00270 }
00271 
00272 
00273 const std::string Gate::get_object_type_name() const {
00274   return std::string("Gate");
00275 }
00276 
00277 void Gate::print(std::ostream & os, int n_tabs) const {
00278 
00279   os
00280     << gen_tabs(n_tabs) << "Gate name        : " << get_name() << std::endl
00281     << gen_tabs(n_tabs) << "Gate description : " << get_description() << std::endl
00282     << gen_tabs(n_tabs) << "Object ID        : " << get_object_id() << std::endl
00283     << gen_tabs(n_tabs) << "Bounding box     : " << Rectangle::get_bounding_box().to_string() << std::endl
00284     << std::endl;
00285 
00286   for(port_const_iterator pi = ports_begin(); pi != ports_end(); ++pi) {
00287     const GatePort_shptr gate_port = *pi;
00288     gate_port->print(os, n_tabs + 1);
00289     os << std::endl;
00290   }
00291 
00292   os << std::endl;
00293 }