|
degate 0.1.1
|
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 }
1.7.4