diff --git a/crlcore/src/ccore/AllianceFramework.cpp b/crlcore/src/ccore/AllianceFramework.cpp index 847517f6..01b83216 100644 --- a/crlcore/src/ccore/AllianceFramework.cpp +++ b/crlcore/src/ccore/AllianceFramework.cpp @@ -13,32 +13,28 @@ // | C++ Module : "./AllianceFramework.cpp" | // +-----------------------------------------------------------------+ - -#include -#include "vlsisapd/utilities/Path.h" -#include "hurricane/Warning.h" -#include "hurricane/Technology.h" -#include "hurricane/DataBase.h" -#include "hurricane/Library.h" -#include "hurricane/Cell.h" -#include "hurricane/Instance.h" -#include "hurricane/viewer/Graphics.h" -#include "crlcore/Utilities.h" -#include "crlcore/GraphicsParser.h" -#include "crlcore/SymbolicTechnologyParser.h" -#include "crlcore/RealTechnologyParser.h" -#include "crlcore/CellGauge.h" -#include "crlcore/RoutingGauge.h" -#include "crlcore/RoutingLayerGauge.h" -#include "crlcore/AllianceFramework.h" - - - +#include +#include "vlsisapd/utilities/Path.h" +#include "hurricane/Warning.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/viewer/Graphics.h" +#include "crlcore/Utilities.h" +#include "crlcore/GraphicsParser.h" +#include "crlcore/SymbolicTechnologyParser.h" +#include "crlcore/RealTechnologyParser.h" +#include "crlcore/CellGauge.h" +#include "crlcore/RoutingGauge.h" +#include "crlcore/RoutingLayerGauge.h" +#include "crlcore/AllianceFramework.h" namespace CRL { - + using namespace std::placeholders; using Hurricane::Warning; using Hurricane::tab; using Hurricane::Graphics; @@ -133,6 +129,7 @@ namespace CRL { db = DataBase::create (); db->put ( AllianceFrameworkProperty::create(this) ); + db->_setCellLoader( bind(&AllianceFramework::cellLoader,this,_1) ); //cmess1 << " o Reading Alliance Environment." << endl; @@ -262,6 +259,15 @@ namespace CRL { } + Cell* AllianceFramework::cellLoader ( const string& rpath ) + { + size_t dot = rpath.rfind('.'); + string cellName = rpath.substr(dot+1); + + return getCell( cellName, Catalog::State::Views ); + } + + Cell* AllianceFramework::getCell ( const string& name, unsigned int mode, unsigned int depth ) { bool createCell = false; diff --git a/crlcore/src/ccore/crlcore/AllianceFramework.h b/crlcore/src/ccore/crlcore/AllianceFramework.h index 53acb7fa..e41b43f1 100644 --- a/crlcore/src/ccore/crlcore/AllianceFramework.h +++ b/crlcore/src/ccore/crlcore/AllianceFramework.h @@ -85,6 +85,7 @@ namespace CRL { void addRoutingGauge ( RoutingGauge* ); void addCellGauge ( CellGauge* ); // Cell Management. + Cell* cellLoader ( const string& rpath ); Cell* getCell ( const string& name , unsigned int mode , unsigned int depth=(unsigned int)-1 ); diff --git a/etesian/src/EtesianEngine.cpp b/etesian/src/EtesianEngine.cpp index a76f207d..d59eacbb 100644 --- a/etesian/src/EtesianEngine.cpp +++ b/etesian/src/EtesianEngine.cpp @@ -453,10 +453,6 @@ namespace Etesian { if (not cmess2.enabled()) dots.disable(); - cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; - //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); - getCell()->flattenNets( Cell::Flags::NoClockFlatten ); - // Coloquinte circuit description data-structures. size_t instancesNb = getCell()->getLeafInstanceOccurrences().getSize(); vector idsToTransf ( instancesNb ); @@ -487,6 +483,10 @@ namespace Etesian { } UpdateSession::close(); + cmess1 << " - Building RoutingPads (transhierarchical) ..." << endl; + //getCell()->flattenNets( Cell::Flags::BuildRings|Cell::Flags::NoClockFlatten ); + getCell()->flattenNets( Cell::Flags::NoClockFlatten ); + index_t instanceId = 0; for ( Occurrence occurrence : getCell()->getLeafInstanceOccurrences() ) { @@ -925,6 +925,14 @@ namespace Etesian { _placed = true; + UpdateSession::open(); + for ( Net* net : getCell()->getNets() ) { + for ( RoutingPad* rp : net->getComponents().getSubSet() ) { + rp->invalidate(); + } + } + UpdateSession::close(); + getCell()->setFlags( Cell::Flags::Placed ); } @@ -999,7 +1007,7 @@ namespace Etesian { ); //cerr << "Setting <" << instanceName << " @" << instancePosition << endl; - // This is temporary as it's not trans-hierarchic: we ignore the posutions + // This is temporary as it's not trans-hierarchic: we ignore the positions // of all the intermediary instances. instance->setTransformation( trans ); instance->setPlacementStatus( Instance::PlacementStatus::PLACED ); diff --git a/hurricane/src/hurricane/Box.cpp b/hurricane/src/hurricane/Box.cpp index 5cb0e291..bad9ce79 100644 --- a/hurricane/src/hurricane/Box.cpp +++ b/hurricane/src/hurricane/Box.cpp @@ -318,7 +318,7 @@ Box& Box::merge(const Box& box) } Box& Box::translate(const DbU::Unit& dx, const DbU::Unit& dy) -// ************************************************ +// ********************************************************** { if (!isEmpty()) { _xMin += dx; @@ -353,6 +353,58 @@ Record* Box::_getRecord() const return record; } +void Box::toJson(JsonWriter* w) const +// *********************************** +{ + w->startObject(); + jsonWrite( w, "@typename", "Box" ); + jsonWrite( w, "_xMin", getXMin() ); + jsonWrite( w, "_yMin", getYMin() ); + jsonWrite( w, "_xMax", getXMax() ); + jsonWrite( w, "_yMax", getYMax() ); + w->endObject(); +} + +JsonBox::JsonBox(unsigned long flags) +// ********************************** + : JsonObject(flags) +{ + add( "_xMin", typeid(int64_t) ); + add( "_yMin", typeid(int64_t) ); + add( "_xMax", typeid(int64_t) ); + add( "_yMax", typeid(int64_t) ); +} + +string JsonBox::getTypeName() const +// ********************************* +{ return "Box"; } + +JsonBox* JsonBox::clone(unsigned long flags) const +// *********************************************** +{ return new JsonBox ( flags ); } + +void JsonBox::toData(JsonStack& stack) +// *********************************** +{ + check( stack, "JsonBox::toData" ); + + DbU::Unit xMin = DbU::fromDb(get(stack,"_xMin")); + DbU::Unit yMin = DbU::fromDb(get(stack,"_yMin")); + DbU::Unit xMax = DbU::fromDb(get(stack,"_xMax")); + DbU::Unit yMax = DbU::fromDb(get(stack,"_yMax")); + + Box box; + + if ( (xMin <= xMax) and (yMin <= yMax) ) + box.merge( xMin, yMin, xMax, yMax ); + + ltrace(51) << "Box(" << xMin << ", " + << yMin << ", " + << xMax << ", " + << yMax << ")" << endl; + + update( stack, box ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index abb9a7c2..55b6b7bc 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -1,11 +1,15 @@ include_directories ( ${HURRICANE_SOURCE_DIR}/src/hurricane + ${CONFIGURATION_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ) set ( includes hurricane/Mask.h hurricane/Flags.h hurricane/DebugSession.h hurricane/Backtrace.h + hurricane/JsonWriter.h + hurricane/JsonReader.h + hurricane/Signature.h hurricane/Observer.h hurricane/BasicLayer.h hurricane/BasicLayers.h hurricane/RegularLayer.h hurricane/RegularLayers.h @@ -90,12 +94,16 @@ hurricane/Views.h hurricane/Warning.h hurricane/TextTranslator.h + hurricane/DesignBlob.h ) set ( cpps Record.cpp Slot.cpp Commons.cpp Flags.cpp Backtrace.cpp + JsonWriter.cpp + JsonReader.cpp + Signature.cpp Exception.cpp Bug.cpp Error.cpp @@ -164,6 +172,7 @@ Marker.cpp Timer.cpp TextTranslator.cpp + DesignBlob.cpp ) add_library ( hurricane ${cpps} ) diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index 81bb29b4..dbabfe17 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -28,6 +28,10 @@ #include "hurricane/Net.h" #include "hurricane/Pin.h" #include "hurricane/RoutingPad.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/Contact.h" +#include "hurricane/Pad.h" #include "hurricane/Layer.h" #include "hurricane/Slice.h" #include "hurricane/Rubber.h" @@ -254,6 +258,91 @@ bool Cell::isUniquifyMaster() const return (not relation) or (relation->getMasterOwner() == this); } +string Cell::getHierarchicalName () const +// ************************************** +{ + return getLibrary()->getHierarchicalName() + "." + getString(getName()); +} + +Entity* Cell::getEntity(const Signature& signature) const +// ****************************************************** +{ + if ( (signature.getType() == Signature::TypeContact ) + or (signature.getType() == Signature::TypeHorizontal) + or (signature.getType() == Signature::TypeVertical ) + or (signature.getType() == Signature::TypePad ) ) { + Net* net = getNet( signature.getName() ); + if (not net) { + cerr << Error( "Cell::getEntity(): Cell %s do have Net %s, signature incoherency." + , getString(getName()).c_str() + , signature.getName().c_str() ) << endl; + return NULL; + } + + ltrace(51) << "Cell::getEntity(): <" << getName() << ">, Net:<" << net->getName() << ">" << endl; + + if (signature.getType() == Signature::TypeContact) { + ltrace(51) << "Looking in Contacts..." << endl; + for ( Contact* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer () == signature.getLayer()) + and (component->getDx () == signature.getDim(Signature::ContactDx)) + and (component->getDy () == signature.getDim(Signature::ContactDy)) + and (component->getWidth () == signature.getDim(Signature::ContactWidth)) + and (component->getHeight() == signature.getDim(Signature::ContactHeight)) ) + return component; + } + } + + if (signature.getType() == Signature::TypeVertical) { + ltrace(51) << "Looking in Verticals..." << endl; + for ( Vertical* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer () == signature.getLayer()) + and (component->getWidth () == signature.getDim(Signature::VerticalWidth)) + and (component->getX () == signature.getDim(Signature::VerticalX)) + and (component->getDySource() == signature.getDim(Signature::VerticalDySource)) + and (component->getDyTarget() == signature.getDim(Signature::VerticalDyTarget)) ) + return component; + } + } + + if (signature.getType() == Signature::TypeHorizontal) { + ltrace(51) << "Looking in Horizontals..." << endl; + for ( Horizontal* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer () == signature.getLayer()) + and (component->getWidth () == signature.getDim(Signature::HorizontalWidth)) + and (component->getY () == signature.getDim(Signature::HorizontalY)) + and (component->getDxSource() == signature.getDim(Signature::HorizontalDxSource)) + and (component->getDxTarget() == signature.getDim(Signature::HorizontalDxTarget)) ) + return component; + } + } + + if (signature.getType() == Signature::TypePad) { + ltrace(51) << "Looking in Pads..." << endl; + for ( Pad* component : getComponents().getSubSet() ) { + ltrace(51) << "| " << component << endl; + if ( (component->getLayer() == signature.getLayer()) + and (component->getBoundingBox().getXMin() == signature.getDim(Signature::PadXMin)) + and (component->getBoundingBox().getYMin() == signature.getDim(Signature::PadYMin)) + and (component->getBoundingBox().getXMax() == signature.getDim(Signature::PadXMax)) + and (component->getBoundingBox().getYMax() == signature.getDim(Signature::PadYMax)) ) + return component; + } + } + + cerr << Error( "Cell::getEntity(): Cannot find a Component of type %d matching Signature." + , signature.getType() ) << endl; + } else { + cerr << Error( "Cell::getEntity(): Signature type %d is unsupported yet." + , signature.getType() ) << endl; + } + + return NULL; +} + Net* Cell::getNet ( const Name& name ) const //****************************************** { @@ -793,6 +882,23 @@ void Cell::notify(unsigned flags) _observers.notify(flags); } +void Cell::_toJson(JsonWriter* writer) const +// ***************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_library" , getLibrary()->getHierarchicalName() ); + jsonWrite( writer, "_name" , getName() ); + jsonWrite( writer, "_abutmentBox", &_abutmentBox ); +} + +void Cell::_toJsonCollections(JsonWriter* writer) const +// ***************************************** +{ + jsonWrite( writer, "+instanceMap", getInstances() ); + jsonWrite( writer, "+netMap" , getNets() ); + Inherit::_toJsonCollections( writer ); +} // **************************************************************************************************** // Cell::Flags implementation @@ -1105,6 +1211,45 @@ void Cell::MarkerSet::_setNextElement(Marker* marker, Marker* nextMarker) const marker->_setNextOfCellMarkerSet(nextMarker); } + + +// **************************************************************************************************** +// JsonCell implementation +// **************************************************************************************************** + +JsonCell::JsonCell(unsigned long flags) +// ************************************ + : JsonEntity(flags) +{ + remove( ".Cell" ); + add( "_library" , typeid(string) ); + add( "_name" , typeid(string) ); + add( "_abutmentBox" , typeid(Box) ); + add( "+instanceMap" , typeid(JsonArray) ); + add( "+netMap" , typeid(JsonArray) ); +} + +string JsonCell::getTypeName() const +// ********************************* +{ return "Cell"; } + +JsonCell* JsonCell::clone(unsigned long flags) const +// ************************************************* +{ return new JsonCell ( flags ); } + +void JsonCell::toData(JsonStack& stack) +// ************************************ +{ + check( stack, "JsonCell::toData" ); + presetId( stack ); + + Cell* cell = Cell::create( DataBase::getDB()->getLibrary( get(stack,"_library") ) + , get(stack,"_name") ); + cell->setAbutmentBox( stack.as("_abutmentBox") ); + + update( stack, cell ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Component.cpp b/hurricane/src/hurricane/Component.cpp index 70f7463a..4405a6df 100644 --- a/hurricane/src/hurricane/Component.cpp +++ b/hurricane/src/hurricane/Component.cpp @@ -378,6 +378,25 @@ void Component::invalidate(bool propagateFlag) } } + +void Component::forceId(unsigned int id) +// ************************************* +{ + if (not inForcedIdMode()) + throw Error( "Component::forceId(): DataBase *must* be in forced id mode to call this method." ); + + if (getId() == id) return; + + bool materialized = isMaterialized(); + if (materialized) unmaterialize(); + if (_net) _net->_getComponentSet()._remove(this); + + setId( id ); + + if (_net) _net->_getComponentSet()._insert(this); + if (materialized) materialize(); +} + void Component::_postCreate() // ************************** { @@ -454,6 +473,20 @@ void Component::_preDestroy() // trace_out(); } +void Component::_toJson( JsonWriter* writer ) const +// ************************************************ +{ + Inherit::_toJson( writer ); + jsonWrite( writer, "_bodyHook", _bodyHook.getNextHook()->toJson() ); +} + +void Component::_toJsonSignature( JsonWriter* writer ) const +// ********************************************************* +{ + jsonWrite( writer, "_net" , getNet()->getName() ); + _toJson( writer ); +} + string Component::_getString() const // ********************************* { @@ -523,10 +556,12 @@ Component::BodyHook::BodyHook(Component* component) : Inherit() { if (!component) - throw Error("Can't create " + _TName("Component::BodyHook") + " : null component"); + throw Error("Can't create " + _getTypeName() + " : null component"); - if (BODY_HOOK_OFFSET == -1) + if (BODY_HOOK_OFFSET == -1) { BODY_HOOK_OFFSET = (unsigned long)this - (unsigned long)component; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Component::BodyHook::getComponent() const @@ -541,6 +576,11 @@ string Component::BodyHook::_getString() const return "<" + _TName("Component::BodyHook") + " " + getString(getComponent()) + ">"; } +Hook* Component::BodyHook::_compToHook(Component* component) +// ************************************************************* +{ return &(component->_bodyHook); } + + // **************************************************************************************************** // Component_Hooks implementation // **************************************************************************************************** @@ -941,6 +981,16 @@ double getArea ( Component* component ) } +// **************************************************************************************************** +// JsonComponent implementation +// **************************************************************************************************** + +JsonComponent::JsonComponent(unsigned long flags) +// ********************************************** + : JsonEntity(flags) +{ + add( "_bodyHook", typeid(string) ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Contact.cpp b/hurricane/src/hurricane/Contact.cpp index ddbaa333..4ec194a5 100644 --- a/hurricane/src/hurricane/Contact.cpp +++ b/hurricane/src/hurricane/Contact.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Contact.h" #include "hurricane/Net.h" #include "hurricane/Layer.h" @@ -334,6 +336,19 @@ void Contact::_preDestroy() // trace_out(); } +void Contact::_toJson(JsonWriter* writer) const +// ******************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_anchorHook", _anchorHook.getNextHook()->toJson() ); + jsonWrite( writer, "_layer" , _layer->getName() ); + jsonWrite( writer, "_dx" , _dx ); + jsonWrite( writer, "_dy" , _dy ); + jsonWrite( writer, "_width" , _width ); + jsonWrite( writer, "_height" , _height ); +} + string Contact::_getString() const // ******************************* { @@ -373,10 +388,12 @@ Contact::AnchorHook::AnchorHook(Contact* contact) : Inherit() { if (!contact) - throw Error("Can't create " + _TName("Contact::AnchorHook") + " : null contact"); + throw Error("Can't create " + _getTypeName() + " : null contact"); - if (ANCHOR_HOOK_OFFSET == -1) - ANCHOR_HOOK_OFFSET = (unsigned long)this - (unsigned long)contact; + if (ANCHOR_HOOK_OFFSET == -1) { + ANCHOR_HOOK_OFFSET = (unsigned long)this - (unsigned long)contact; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Contact::AnchorHook::getComponent() const @@ -391,6 +408,16 @@ string Contact::AnchorHook::_getString() const return "<" + _TName("Contact::AnchorHook") + " " + getString(getComponent()) + ">"; } +Hook* Contact::AnchorHook::_compToHook(Component* component) +// *************************************************************** +{ + Contact* contact = dynamic_cast(component); + if (not contact) { + throw Error( "AnchorHook::_compToAnchorhook(): Unable to cast %s into Contact*." + , getString(component).c_str() ); + } + return &(contact->_anchorHook); +} // **************************************************************************************************** @@ -508,6 +535,54 @@ string Contact_Hooks::Locator::_getString() const return s; } + + +// **************************************************************************************************** +// JsonContact implementation +// **************************************************************************************************** + +JsonContact::JsonContact(unsigned long flags) +// ****************************************** + : JsonComponent(flags) +{ + add( "_anchorHook", typeid(string) ); + add( "_layer" , typeid(string) ); + add( "_dx" , typeid(int64_t) ); + add( "_dy" , typeid(int64_t) ); + add( "_width" , typeid(int64_t) ); + add( "_height" , typeid(int64_t) ); +} + +string JsonContact::getTypeName() const +// ************************************ +{ return "Contact"; } + +JsonContact* JsonContact::clone(unsigned long flags) const +// ******************************************************* +{ return new JsonContact ( flags ); } + +void JsonContact::toData(JsonStack& stack) +// *************************************** +{ + check( stack, "JsonContact::toData" ); + unsigned int jsonId = presetId( stack ); + + Contact* contact = Contact::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , DbU::fromDb( get(stack,"_dx" ) ) + , DbU::fromDb( get(stack,"_dy" ) ) + , DbU::fromDb( get(stack,"_width" ) ) + , DbU::fromDb( get(stack,"_height") ) + ); + + stack.addHookLink( contact->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + stack.addHookLink( contact->getAnchorHook(), jsonId, get(stack,"_anchorHook") ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, contact ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DBo.cpp b/hurricane/src/hurricane/DBo.cpp index 53431460..300434eb 100644 --- a/hurricane/src/hurricane/DBo.cpp +++ b/hurricane/src/hurricane/DBo.cpp @@ -18,8 +18,6 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// // +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | @@ -65,7 +63,6 @@ namespace Hurricane { void DBo::destroy () { _preDestroy(); - delete this; } @@ -151,6 +148,22 @@ namespace Hurricane { } + void DBo::_toJson ( JsonWriter* writer ) const + { } + + + void DBo::_toJsonSignature ( JsonWriter* writer ) const + { _toJson( writer ); } + + + void DBo::_toJsonCollections ( JsonWriter* writer ) const + { + writer->key( "+propertySet" ); + writer->startArray(); + writer->endArray(); + } + + string DBo::_getTypeName () const { return "DBo"; @@ -171,4 +184,36 @@ namespace Hurricane { } + void DBo::toJsonSignature ( JsonWriter* w ) const + { + w->startObject(); + std::string tname = "Signature." + _getTypeName(); + jsonWrite( w, "@typename", tname ); + _toJsonSignature( w ); + w->endObject(); + } + + + void DBo::toJson ( JsonWriter* w ) const + { + w->startObject(); + std::string tname = _getTypeName(); + if (w->issetFlags(JsonWriter::UsePlugReference) and (tname == "Plug")) { + tname.insert( 0, "&" ); + } + jsonWrite( w, "@typename", tname ); + _toJson( w ); + _toJsonCollections( w ); + w->endObject(); + } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + + JsonDBo::JsonDBo ( unsigned int flags ) + : JsonObject(flags) + { } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DataBase.cpp b/hurricane/src/hurricane/DataBase.cpp index a8971688..d3b8b2d9 100644 --- a/hurricane/src/hurricane/DataBase.cpp +++ b/hurricane/src/hurricane/DataBase.cpp @@ -18,6 +18,7 @@ // **************************************************************************************************** #include "hurricane/DataBase.h" +#include "hurricane/SharedPath.h" #include "hurricane/Technology.h" #include "hurricane/Library.h" #include "hurricane/Error.h" @@ -81,7 +82,7 @@ string DataBase::_getString() const } Record* DataBase::_getRecord() const -// *************************** +// ********************************* { Record* record = Inherit::_getRecord(); if (record) { @@ -100,7 +101,55 @@ DataBase* DataBase::getDB() return _db; } +Library* DataBase::getLibrary(string rpath) const +// ********************************************** +{ + Library* current = getRootLibrary(); + if (not current) return NULL; + char separator = SharedPath::getNameSeparator(); + Name childName; + size_t dot = rpath.find( separator ); + if (dot != string::npos) { + childName = rpath.substr( 0, dot ); + rpath = rpath.substr( dot+1 ); + } else + childName = rpath; + + if (childName != current->getName()) + return NULL; + + while ( dot != string::npos ) { + dot = rpath.find( separator ); + if (dot != string::npos) { + childName = rpath.substr( 0, dot ); + rpath = rpath.substr( dot+1 ); + } else + childName = rpath; + + current = current->getLibrary( childName ); + } + return current; +} + +Cell* DataBase::getCell(string rpath) const +// **************************************** +{ + + char separator = SharedPath::getNameSeparator(); + size_t dot = rpath.rfind( separator ); + string cellName = rpath.substr(dot+1); + Library* library = getLibrary( rpath.substr(0,dot) ); + Cell* cell = NULL; + + if (library) + cell = library->getCell( rpath.substr(dot+1) ); + + if (not cell and _cellLoader) return _cellLoader( rpath ); + + return cell; + +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DeepNet.cpp b/hurricane/src/hurricane/DeepNet.cpp index 00794bd0..21854632 100644 --- a/hurricane/src/hurricane/DeepNet.cpp +++ b/hurricane/src/hurricane/DeepNet.cpp @@ -49,7 +49,6 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "DeepNet". - DeepNet::DeepNet ( Occurrence& netOccurrence ) : Net(netOccurrence.getOwnerCell() ,netOccurrence.getName() @@ -122,4 +121,61 @@ namespace Hurricane { } + void DeepNet::_toJson( JsonWriter* writer ) const + { + Inherit::_toJson( writer ); + + jsonWrite( writer, "_netOccurrence", &_netOccurrence ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonDeepNet". + + JsonDeepNet::JsonDeepNet ( unsigned long flags ) + : JsonNet(flags) + { + ltrace(51) << "JsonDeepNet::JsonDeepNet()" << endl; + + add( "_netOccurrence", typeid(Occurrence) ); + } + + + JsonDeepNet::~JsonDeepNet () + { } + + + string JsonDeepNet::getTypeName () const + { return "DeepNet"; } + + + JsonDeepNet* JsonDeepNet::clone ( unsigned long flags ) const + { return new JsonDeepNet ( flags ); } + + + void JsonDeepNet::toData(JsonStack& stack) + { + ltracein(51); + + _stack = &stack; + + check( stack, "JsonDeepNet::toData" ); + presetId( stack ); + + HyperNet hyperNet ( get(stack,"_netOccurrence") ); + + _net = DeepNet::create( hyperNet ); + _net->setGlobal ( get(stack,"_isGlobal" ) ); + _net->setExternal ( get(stack,"_isExternal" ) ); + _net->setAutomatic( get(stack,"_isAutomatic") ); + _net->setType ( Net::Type (get(stack,"_type")) ); + _net->setDirection( Net::Direction(get(stack,"_direction")) ); + + setName( ".Net" ); + update( stack, _net ); + + ltraceout(51); + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/DesignBlob.cpp b/hurricane/src/hurricane/DesignBlob.cpp new file mode 100644 index 00000000..2db3868b --- /dev/null +++ b/hurricane/src/hurricane/DesignBlob.cpp @@ -0,0 +1,74 @@ +// -*- mode: C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./DesignBlob.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/DesignBlob.h" +#include "hurricane/DataBase.h" +#include "hurricane/Library.h" +#include "hurricane/DesignBlob.h" + + +namespace Hurricane { + + using std::cerr; + using std::endl; + + +// ------------------------------------------------------------------- +// Class : "DesignBlob". + + void DesignBlob::toJson( JsonWriter* w ) const + { + w->startObject(); + jsonWrite( w, "@typename", _getTypeName() ); + jsonWrite( w, "_topCell" , getTopCell()->getHierarchicalName() ); + jsonWrite( w, "_library" , DataBase::getDB()->getRootLibrary() ); + w->endObject(); + } + + +// ------------------------------------------------------------------- +// Class : "JsonDesignBlob". + + JsonDesignBlob::JsonDesignBlob ( unsigned long flags ) + : JsonObject(flags) + { + ltrace(51) << "JsonDesignblob::JsonDesignblob()" << endl; + + add( "_library", typeid(Library*) ); + add( "_topCell", typeid(string) ); + } + + + string JsonDesignBlob::getTypeName () const + { return "DesignBlob"; } + + + JsonDesignBlob* JsonDesignBlob::clone ( unsigned long flags ) const + { return new JsonDesignBlob ( flags ); } + + + void JsonDesignBlob::toData ( JsonStack& stack ) + { + check( stack, "JsonDesignBlob::toData" ); + + DesignBlob* designBlob = new DesignBlob ( DataBase::getDB()->getCell(get(stack,"_topCell")) ); + + update( stack, designBlob ); + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/Entity.cpp b/hurricane/src/hurricane/Entity.cpp index 34e74d95..8a455e71 100644 --- a/hurricane/src/hurricane/Entity.cpp +++ b/hurricane/src/hurricane/Entity.cpp @@ -28,22 +28,73 @@ namespace Hurricane { - // **************************************************************************************************** // Entity implementation // **************************************************************************************************** - unsigned int Entity::_idCounter = 0; + unsigned long Entity::_flags = 0; + unsigned int Entity::_nextId = 0; + unsigned int Entity::_idCounter = 1; unsigned int Entity::getIdCounter () { return _idCounter; } + bool Entity::inForcedIdMode () + { return _flags & ForcedIdMode; } + + + void Entity::enableForcedIdMode () + { + if (_flags & ForcedIdMode) return; + if (_idCounter != 1) { + throw Error( "Entity::enableForcedIdMode(): DataBase must be reset before forcind ids." ); + } + _flags |= ForcedIdMode; + } + + + void Entity::disableForcedIdMode () + { + if (not (_flags & ForcedIdMode)) return; + _flags &= ~ForcedIdMode; + } + + + void Entity::setNextId ( unsigned int nid ) + { + if (not (_flags & ForcedIdMode)) { + cerr << Error("Entity::setNextId(): Not in forced id mode, ignored.") << endl; + return; + } + _nextId = nid; + if (nid > _idCounter) _idCounter = nid; + _flags |= NextIdSet; + } + + + unsigned int Entity::getNextId () + { + if (_flags & ForcedIdMode) { + if (_flags & NextIdSet) { + _flags &= ~NextIdSet; + ltrace(51) << demangle(typeid(*this).name()) + << "::getNextId(): Consuming the preset id:" << _nextId << endl; + return _nextId; + } else { + throw Error("Entity::getNextId(): Next id is not set, while in forced id mode."); + } + } + + return _idCounter++; + } + + Entity::Entity() : Inherit() - , _id(_idCounter++) + , _id (getNextId()) { if (_idCounter == std::numeric_limits::max()) { throw Error( "Entity::Entity(): Identifier counter has reached it's limit (%d bits)." @@ -96,28 +147,53 @@ namespace Hurricane { //ltraceout(10); } -string Entity::_getString() const -// ****************************** -{ - string s = Inherit::_getString(); - s.insert(1, "id:"+getString(_id)+" "); - return s; -} -Record* Entity::_getRecord() const -// ************************* -{ + void Entity::setId ( unsigned int id ) + { + if (_flags & ForcedIdMode) { + _id = id; + if (_id > _idCounter) _idCounter = _id; + } else { + throw Error("Entity::setId(): Attempt to set id while not in forced id mode."); + } + } + + + void Entity::_toJson ( JsonWriter* writer ) const + { + Inherit::_toJson( writer ); + + jsonWrite( writer, "_id", getId() ); + } + + + string Entity::_getString() const + { + string s = Inherit::_getString(); + s.insert( 1, "id:"+getString(_id)+" " ); + return s; + } + + + Record* Entity::_getRecord() const + { Record* record = Inherit::_getRecord(); if (record) { - record->add(getSlot("_id", _id)); - Occurrence occurrence = Occurrence(this); - if (occurrence.hasProperty()) - record->add(getSlot("Occurrence", occurrence)); + record->add( getSlot("_id", _id) ); + Occurrence occurrence = Occurrence(this); + if (occurrence.hasProperty()) + record->add( getSlot("Occurrence", occurrence) ); } return record; -} + } + JsonEntity::JsonEntity (unsigned long flags) + : JsonDBo(flags) + { + add( "_id", typeid(uint64_t) ); + } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Hook.cpp b/hurricane/src/hurricane/Hook.cpp index aab27b2e..b20c0742 100644 --- a/hurricane/src/hurricane/Hook.cpp +++ b/hurricane/src/hurricane/Hook.cpp @@ -187,6 +187,9 @@ class Hook_SlaveHooks : public Collection { // Hook implementation // **************************************************************************************************** +map Hook::_compToHookMap; + + Hook::Hook() // ********* : _nextHook(this) @@ -385,7 +388,30 @@ Record* Hook::_getRecord() const return record; } +string Hook::toJson() const +// ************************ +{ + if (_nextHook == this) return ""; + string s = _getTypeName()+"."+getString(getComponent()->getId()); + return s; +} +void Hook::addCompToHook(const string& tname, Hook::compToHook_t converter) +// ************************************************************************ +{ + _compToHookMap.insert( make_pair(tname,converter) ); +} + +Hook* Hook::compToHook(const string& tname, Component* component) +// ************************************************************** +{ + map::const_iterator iconv = _compToHookMap.find(tname); + if (iconv == _compToHookMap.end()) { + throw Error( "Hook::fromJson(): No converter registered for type name \"%s\"" + , tname.c_str() ); + } + return (*iconv).second(component); +} // **************************************************************************************************** // Hook_Hooks implementation diff --git a/hurricane/src/hurricane/Horizontal.cpp b/hurricane/src/hurricane/Horizontal.cpp index 0d013308..67d478df 100644 --- a/hurricane/src/hurricane/Horizontal.cpp +++ b/hurricane/src/hurricane/Horizontal.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Horizontal.h" #include "hurricane/Layer.h" #include "hurricane/BasicLayer.h" @@ -173,6 +175,16 @@ void Horizontal::translate(const DbU::Unit& dy) } } +void Horizontal::_toJson(JsonWriter* writer) const +// *********************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_y" , _y ); + jsonWrite( writer, "_dxSource", _dxSource ); + jsonWrite( writer, "_dxTarget", _dxTarget ); +} + string Horizontal::_getString() const // ********************************** { @@ -191,6 +203,51 @@ Record* Horizontal::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonHorizontal implementation +// **************************************************************************************************** + +JsonHorizontal::JsonHorizontal(unsigned long flags) +// ************************************************ + : JsonSegment(flags) +{ + add( "_y" , typeid(uint64_t) ); + add( "_dxSource", typeid(uint64_t) ); + add( "_dxTarget", typeid(uint64_t) ); +} + +string JsonHorizontal::getTypeName() const +// *************************************** +{ return "Horizontal"; } + +JsonHorizontal* JsonHorizontal::clone(unsigned long flags) const +// ************************************************************* +{ return new JsonHorizontal ( flags ); } + +void JsonHorizontal::toData(JsonStack& stack) +// ****************************************** +{ + check( stack, "JsonHorizontal::toData" ); + unsigned int jsonId = presetId( stack ); + + Horizontal* horizontal = Horizontal::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , DbU::fromDb( get(stack,"_y" ) ) + , DbU::fromDb( get(stack,"_width" ) ) + , DbU::fromDb( get(stack,"_dxSource") ) + , DbU::fromDb( get(stack,"_dxTarget") ) + ); + + stack.addHookLink( horizontal->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + stack.addHookLink( horizontal->getSourceHook(), jsonId, get(stack,"_sourceHook") ); + stack.addHookLink( horizontal->getTargetHook(), jsonId, get(stack,"_targetHook") ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, horizontal ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Instance.cpp b/hurricane/src/hurricane/Instance.cpp index ae5dbb9e..260ed11b 100644 --- a/hurricane/src/hurricane/Instance.cpp +++ b/hurricane/src/hurricane/Instance.cpp @@ -20,6 +20,7 @@ #include "hurricane/Warning.h" #include "hurricane/UpdateSession.h" #include "hurricane/SharedPath.h" +#include "hurricane/DataBase.h" #include "hurricane/Instance.h" #include "hurricane/Cell.h" #include "hurricane/Net.h" @@ -30,7 +31,6 @@ namespace Hurricane { - // **************************************************************************************************** // Filters declaration & implementation // **************************************************************************************************** @@ -201,7 +201,10 @@ Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, bool // **************************************************************************************** { if (not cell) - throw Error( "Instance::create(): NULL master Cell argument." ); + throw Error( "Instance::create(): NULL owner Cell argument for %s.", getString(name).c_str() ); + + if (not masterCell) + throw Error( "Instance::create(): NULL master Cell argument for %s.", getString(name).c_str() ); // if (cell->isUniquified()) // throw Error( "Instance::create(): %s master Cell is an uniquified copy.", getString(cell).c_str() ); @@ -217,7 +220,10 @@ Instance* Instance::create(Cell* cell, const Name& name, Cell* masterCell, const // ********************************************************************************************************************************************************************** { if (not cell) - throw Error( "Instance::create(): NULL master Cell argument." ); + throw Error( "Instance::create(): NULL owner Cell argument for %s.", getString(name).c_str() ); + + if (not masterCell) + throw Error( "Instance::create(): NULL master Cell argument for %s.", getString(name).c_str() ); // if (cell->isUniquified()) // throw Error( "Instance::create(): %s master Cell is an uniquified copy.", getString(cell).c_str() ); @@ -489,6 +495,15 @@ void Instance::uniquify() ) << endl; return; } + + if (not _getSharedPathMap().isEmpty()) { + cerr << Warning( "Instance::uniquify(): While uniquifying model %s of instance %s, SharedPathMap is not empty.\n" + " (Entity's Occurrences will still uses the original master Cell)" + , getString(_masterCell->getName()).c_str() + , getString(getName()).c_str() + ) << endl; + } + setMasterCell( _masterCell->getClone() ); } @@ -512,6 +527,13 @@ Instance* Instance::getClone(Cell* cloneCell) const , getPlacementStatus() ); + if (not clone->_getSharedPathMap().isEmpty()) { + cerr << Warning( "Instance::getClone(): While cloning instance %s, SharedPathMap is not empty.\n" + " (Occurrence will still uses the original instance)" + , getString(getName()).c_str() + ) << endl; + } + for( Plug* iplug : getPlugs() ) { if (iplug->isConnected()) { Plug* clonePlug = clone->getPlug( iplug->getMasterNet() ); @@ -595,6 +617,24 @@ Record* Instance::_getRecord() const return record; } +void Instance::_toJson( JsonWriter* writer ) const +// *********************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_name" , getName() ); + jsonWrite( writer, "_masterCell" , _masterCell->getHierarchicalName() ); + jsonWrite( writer, "_transformation" , &_transformation ); + jsonWrite( writer, "_placementStatus", _placementStatus ); +} + +void Instance::_toJsonCollections(JsonWriter* writer) const +// ******************************************************** +{ + jsonWrite( writer, "+plugMap", getPlugs() ); + Inherit::_toJsonCollections( writer ); +} + // **************************************************************************************************** // Instance::PlugMap implementation // **************************************************************************************************** @@ -672,13 +712,20 @@ void Instance::SharedPathMap::_setNextElement(SharedPath* sharedPath, SharedPath Instance::PlacementStatus::PlacementStatus(const Code& code) // ********************************************************* : _code(code) -{ -} +{ } Instance::PlacementStatus::PlacementStatus(const PlacementStatus& placementstatus) // ******************************************************************************* : _code(placementstatus._code) +{ } + +Instance::PlacementStatus::PlacementStatus(string s) +// ************************************************* +: _code(UNPLACED) { + if (s == "UNPLACED") _code = UNPLACED; + else if (s == "PLACED" ) _code = PLACED; + else if (s == "FIXED" ) _code = FIXED; } Instance::PlacementStatus& Instance::PlacementStatus::operator=(const PlacementStatus& placementstatus) @@ -702,6 +749,47 @@ Record* Instance::PlacementStatus::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonInstance implementation +// **************************************************************************************************** + +JsonInstance::JsonInstance(unsigned long flags) +// ******************************************** + : JsonEntity(flags) +{ + add( "_name" , typeid(string) ); + add( "_masterCell" , typeid(string) ); + add( "_transformation" , typeid(Transformation*) ); + add( "_placementStatus", typeid(string) ); + add( "+plugMap" , typeid(JsonArray) ); +} + +string JsonInstance::getTypeName() const +// ************************************* +{ return "Instance"; } + +JsonInstance* JsonInstance::clone(unsigned long flags) const +// ********************************************************* +{ return new JsonInstance ( flags ); } + +void JsonInstance::toData(JsonStack& stack) +// **************************************** +{ + check( stack, "JsonInstance::toData" ); + presetId( stack ); + + Instance* instance = Instance::create + ( get(stack,".Cell") + , get(stack,"_name") + , DataBase::getDB()->getCell( get(stack,"_masterCell") ) + , get(stack,"_transformation") + , Instance::PlacementStatus(get(stack,"_placementStatus") ) + ); + + update( stack, instance ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/JsonReader.cpp b/hurricane/src/hurricane/JsonReader.cpp new file mode 100644 index 00000000..beb50f92 --- /dev/null +++ b/hurricane/src/hurricane/JsonReader.cpp @@ -0,0 +1,821 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./JsonReader.cpp" | +// +-----------------------------------------------------------------+ + + +#include "rapidjson/filereadstream.h" +#include "rapidjson/reader.h" +// Needed for registering. May be deleted later. +#include "hurricane/DebugSession.h" +#include "hurricane/Warning.h" +#include "hurricane/JsonReader.h" +#include "hurricane/Library.h" +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/DeepNet.h" +#include "hurricane/Instance.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/DesignBlob.h" + + +namespace { + + using namespace std; + using namespace rapidjson; + using namespace Hurricane; + + class JsonReader; + + +// ------------------------------------------------------------------- +// Class : "HurricaneHandler" (declaration). + + class HurricaneHandler { + public: + HurricaneHandler ( JsonReader& ); + public: + bool Null (); + bool Bool ( bool ); + bool Int ( int ); + bool Int64 ( int64_t ); + bool Uint ( unsigned int ); + bool Uint64 ( uint64_t ); + bool Double ( double ); + bool String ( const char*, SizeType, bool copy ); + bool Key ( const char*, SizeType, bool copy ); + bool StartObject (); + bool EndObject ( SizeType ); + bool StartArray (); + bool EndArray ( SizeType ); + inline bool isDummy () const; + inline bool doCallToData () const; + inline JsonStack& stack (); + inline unsigned long flags (); + private: + enum Flags { TypenameKey = (1<<0) + }; + private: + unsigned long _state; + string _key; + string _objectName; + vector _objects; + JsonReader& _reader; + }; + + +// ------------------------------------------------------------------- +// Class : "JsonReader" (declaration). + + class JsonReader { + public: + JsonReader ( unsigned long flags ); + ~JsonReader (); + inline JsonReader* setFlags ( unsigned long mask ); + inline JsonReader* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + inline unsigned long getFlags () const; + inline JsonStack& getStack (); + void parse ( std::string fileName ); + void close (); + private: + JsonReader ( const JsonReader& ); + JsonReader& operator= ( const JsonReader& ) const; + private: + unsigned long _flags; + size_t _bufferSize; + char* _buffer; + FILE* _file; + FileReadStream* _stream; + JsonStack _stack; + Reader _reader; + HurricaneHandler _handler; + }; + + +// ------------------------------------------------------------------- +// Class : "HurricaneHandler" (definition). + + HurricaneHandler::HurricaneHandler ( JsonReader& reader ) + : _state (0) + , _key () + , _objectName() + , _objects () + , _reader (reader) + { } + + + inline JsonStack& HurricaneHandler::stack () { return _reader.getStack(); } + inline unsigned long HurricaneHandler::flags () { return _reader.getFlags(); } + + + inline bool HurricaneHandler::isDummy () const + { return _objects.empty() or _objects.back()->isDummy(); } + + + inline bool HurricaneHandler::doCallToData () const + { return not _objects.empty() and _objects.back() and not _objects.back()->isBound(); } + + + bool HurricaneHandler::Null () + { + if (isDummy()) return true; + stack().push_back( _key, NULL ); + return true; + } + + + bool HurricaneHandler::Bool ( bool v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int ( int v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int64 ( int64_t v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint ( unsigned int v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint64 ( uint64_t v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Double ( double v ) + { + if (isDummy()) return true; + stack().push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::String ( const char* value, SizeType, bool copy ) + { + if (isDummy() and not (_state & TypenameKey)) return true; + if (_state & TypenameKey) { + _state &= ~TypenameKey; + + if (_key != "@typename") { + cerr << Warning("JsonReader::parse(): First field is not @typename, skipping object." ) << endl; + return true; + } + + string svalue = value; + JsonObject* object = NULL; + JsonSignature* signature = NULL; + if (svalue.compare(0,10,"Signature.") == 0) object = JsonTypes::find( "Signature" ); + else object = JsonTypes::find( value ); + + if (not object) { + // Keep the dummy object on top of the stack. + cerr << Warning( "JsonReader::parse(): Do not know how to parse type \"%s\" (ignored)." + , value ) << endl; + dynamic_cast(_objects.back())->setTypeName( value ); + } else { + // Replace the dummy object on top of the stack. + delete _objects.back(); + _objects[_objects.size()-1] = object->clone( flags() ); + _objects.back()->setName( _objectName ); + + signature = dynamic_cast( _objects.back() ); + if (signature) { + size_t dot = svalue.find('.'); + signature->setSubType( svalue.substr(dot+1) ); + } + } + + ltrace(51) << "HurricaneHandler::String() [key/typename] \"" << value << "\"." << endl; + return true; + } + + stack().push_back( _key, value ); + return true; + } + + + bool HurricaneHandler::Key ( const char* key, SizeType, bool copy ) + { + if (isDummy() and not (_state & TypenameKey)) return true; + + _key = key; + if (_state & TypenameKey) return true; + + //ltrace(51) << "HurricaneHandler::Key() key:" << _key << " _objects.size():" << _objects.size() << endl; + + if (_objects.back()) { + if ( doCallToData() and not _key.empty() and (_key[0] != '_') ) { + // The key is no longer a simple attribute of the object. + // Triggers it's creation in the Json stack. + ltrace(51) << "HurricaneHandler::key() Calling " + << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( stack() ); + } + } + + return true; + } + + + bool HurricaneHandler::StartObject () + { + ltrace(50) << "Hurricane::StartObject()" << endl; + ltracein(50); + + _state |= TypenameKey; + _objectName = (_key == ".Array") ? "" : _key; + _objects.push_back( new JsonDummy() ); + ltrace(51) << "_objects.push_back(NULL), size():" << _objects.size() << "." << endl; + + ltracein(50); + return true; + } + + + bool HurricaneHandler::EndObject ( SizeType ) + { + ltraceout(50,2); + ltrace(50) << "HurricaneHandler::EndObject()" << endl; + ltracein(50); + + _objectName.clear(); + if (not isDummy()) { + if (doCallToData()) { + ltrace(51) << "Calling " << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( stack() ); + } + if (stack().size() > 1) { + if (stack()[-1].first[0] != '_') stack().pop_back(); + } + } + + //if (_objects.size() > 1) { + ltrace(51) << "_objects.pop_back(), size():" << _objects.size() << "." << endl; + delete _objects.back(); + _objects.pop_back(); + //} + + ltraceout(50); + return true; + } + + + bool HurricaneHandler::StartArray() + { + ltrace(50) << "HurricaneHandler::StartArray() key:\"" << _key << "\"." << endl; + ltracein(50); + + _objectName.clear(); + if (_key[0] != '+') { + cerr << Warning("JsonReader::parse(): Array attributes must start by \'+\' %s.", _key.c_str() ) << endl; + return true; + } + + _key = ".Array"; + return true; + } + + bool HurricaneHandler::EndArray ( SizeType ) + { + ltraceout(50); + ltrace(50) << "HurricaneHandler::EndArray()" << endl; + ltracein(50); + + _key.clear(); + + ltraceout(50); + return true; + } + + +// ------------------------------------------------------------------- +// Class : "JsonReader" (definition). + + JsonReader::JsonReader ( unsigned long flags ) + : _flags (flags) + , _bufferSize(65536) + , _buffer (new char [_bufferSize]) + , _file (NULL) + , _stream (NULL) + , _stack () + , _reader () + , _handler (*this) + { + } + + + JsonReader::~JsonReader () + { + close(); + delete _buffer; + } + + + void JsonReader::close () + { + if (_stream) { delete _stream; _stream = NULL; } + if (_file ) { fclose(_file); _file = NULL; } + } + + + inline JsonReader* JsonReader::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonReader* JsonReader::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonReader::issetFlags ( unsigned long mask ) const { return _flags & mask; } + inline unsigned long JsonReader::getFlags () const { return _flags; } + inline JsonStack& JsonReader::getStack () { return _stack; } + + + void JsonReader::parse ( string fileName ) + { + close(); + + DebugSession::open( 50 ); + + fileName += ".json"; + _file = fopen( fileName.c_str(), "r" ); + ltrace(50) << "_file:" << _file << ", _buffer:" << (void*)_buffer << endl; + + if (not _file) { + throw Error( "JsonReader::parse(): Cannot open file \"%s\"." + , fileName.c_str() ); + } + + _stream = new FileReadStream ( _file, _buffer, _bufferSize ); + + if (issetFlags(JsonWriter::DesignBlobMode)) + Entity::enableForcedIdMode(); + _reader.Parse( *_stream, _handler ); + _stack.print( cerr ); + if (issetFlags(JsonWriter::DesignBlobMode)) + Entity::disableForcedIdMode(); + + DebugSession::close(); + close(); + } + + +} // local namespace. + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + JsonObject::JsonObject ( unsigned long flags ) + : _flags (flags) + , _name () + , _stackeds () + , _attributes () + , _collections() + , _object () + { } + + + JsonObject::~JsonObject () + { } + + + bool JsonObject::isDummy () const + { return false; } + + + void JsonObject::add ( const string& key, type_index tid ) + { + if (key.empty()) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute with an empty name, ignored." + << endl; + return; + } + if (has(key)) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute \"" << key << "\" twice, cancelled." + << endl; + return; + } + + switch ( key[0] ) { + case '.': _stackeds .push_back( JsonAttribute(key,tid) ); return; + case '_': _attributes .push_back( JsonAttribute(key,tid) ); return; + case '+': _collections.push_back( JsonAttribute(key,tid) ); return; + default: break; + } + + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + void JsonObject::remove ( const std::string& key ) + { + if (key.empty()) { + cerr << Error( "JsonObject::remove(): Attempt to remove attribute with an empty name, ignored." ) << endl; + return; + } + + switch ( key[0] ) { + case '.': + for ( auto it = _stackeds.begin() ; it != _stackeds.end() ; ++it ) + if (key == (*it).key()) { _stackeds.erase(it); break; } + break; + case '_': + for ( auto it = _attributes.begin() ; it != _attributes.end() ; ++it ) + if (key == (*it).key()) { _attributes.erase(it); break; } + break; + case '+': + for ( auto it = _collections.begin() ; it != _collections.end() ; ++it ) + if (key == (*it).key()) { _collections.erase(it); break; } + break; + } + } + + + bool JsonObject::has ( const std::string& key ) const + { + if (key.empty()) return false; + switch ( key[0] ) { + case '.': + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + if (key == _stackeds[i].key()) return true; + break; + case '_': + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + if (key == _attributes[i].key()) return true; + break; + case '+': + for ( size_t i=0 ; i<_collections.size() ; ++i ) + if (key == _collections[i].key()) return true; + break; + } + return false; + } + + + bool JsonObject::check ( JsonStack& stack, string fname ) const + { + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) { + if (not stack.rhas(_stackeds[i].key())) { + cerr << Error( "%s(): Stack is missing context element with key \"%s\"" + , fname.c_str(), _stackeds[i].key().c_str() ) << endl; + return false; + } + } + for ( size_t i=0 ; i<_attributes.size() ; ++i ) { + if (not stack.rhas(_attributes[i].key())) { + cerr << Error( "%s(): Stack is missing attribute element with key \"%s\"" + , fname.c_str(), _attributes[i].key().c_str() ) << endl; + return false; + } + } + return true; + } + + + void JsonObject::toData ( JsonStack& ) + { } + + + unsigned int JsonObject::presetId ( JsonStack& stack ) + { + unsigned int jsonId = get( stack, "_id" ); + if (issetFlags(JsonWriter::DesignBlobMode)) { + Entity::setNextId( jsonId ); + } + return jsonId; + } + + + void JsonObject::print ( ostream& o ) const + { + o << tab << "JsonObject for type: " << getTypeName() << endl; + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _stackeds[i].key() + << " type:" << _stackeds[i].tid().name() << endl; + + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _attributes[i].key() + << " type:" << _attributes[i].tid().name() << endl; + + for ( size_t i=0 ; i<_collections.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _collections[i].key() + << " type:" << _collections[i].tid().name() << endl; + } + + +// ------------------------------------------------------------------- +// Class : "JsonKey". + + JsonKey::JsonKey ( const string& key ) + : JsonObject(0) + , _key (key) + { } + + + string JsonKey::getTypeName () const { return _key; } + JsonKey* JsonKey::clone ( unsigned long ) const { return new JsonKey ( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonDummy". + + JsonDummy::JsonDummy () + : JsonObject(0) + , _typename ("dummy") + { } + + + bool JsonDummy::isDummy () const { return true; } + string JsonDummy::getTypeName () const { return _typename; } + void JsonDummy::setTypeName ( const string& name ) { _typename=name; } + JsonDummy* JsonDummy::clone ( unsigned long ) const { return new JsonDummy ( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + JsonTypes* JsonTypes::_jsonTypes = NULL; + + + JsonTypes::JsonTypes () + : _jsonObjects() + { } + + + JsonTypes::~JsonTypes () + { + for ( JsonObject* object : _jsonObjects ) delete object; + } + + + void JsonTypes::_registerType ( JsonObject* object ) + { + if (_find(object->getTypeName())) { + throw Error( "JsonTypes::_registerType(): Attempt to register <%s> twice.", object->getTypeName().c_str() ); + } + _jsonObjects.insert( object ); + } + + + JsonObject* JsonTypes::_find ( const string& tname ) + { + JsonKey key( tname ); + set::iterator it = _jsonObjects.find( &key ); + if (it != _jsonObjects.end()) return (*it); + return NULL; + } + + + void JsonTypes::registerType ( JsonObject* object ) + { + if (not _jsonTypes) initialize(); + _jsonTypes->_registerType( object ); + } + + + JsonObject* JsonTypes::find ( const string& tname ) + { + if (not _jsonTypes) initialize(); + return _jsonTypes->_find( tname ); + } + + + void JsonTypes::initialize () + { + if (_jsonTypes) return; + + _jsonTypes = new JsonTypes (); + _jsonTypes->_registerType( new JsonPoint (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonBox (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonTransformation(JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonLibrary (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonCell (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonNet (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonDeepNet (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonPlugRef (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonRoutingPad (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonContact (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonVertical (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonHorizontal (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonPad (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonInstance (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonPlug (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonOccurrence (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonSignature (JsonWriter::RegisterMode) ); + _jsonTypes->_registerType( new JsonDesignBlob (JsonWriter::RegisterMode) ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + void JsonStack::addEntity ( unsigned int jsonId, Entity* entity ) + { _entities.insert( std::make_pair(jsonId,entity) ); } + + + void JsonStack::addHookLink ( Hook* hook, unsigned int jsonId, const string& jsonNext ) + { + if (jsonNext.empty()) return; + + unsigned int id = jsonId; + string tname = hook->_getTypeName(); + + auto ielement = _hooks.find( HookKey(id,tname) ); + if (ielement == _hooks.end()) { + auto r = _hooks.insert( make_pair( HookKey(id,tname), HookElement(hook) ) ); + ielement = r.first; + (*ielement).second.setFlags( HookElement::OpenRingStart ); + } + HookElement* current = &((*ielement).second); + if (not current->hook()) current->setHook( hook ); + + hookFromString( jsonNext, id, tname ); + ielement = _hooks.find( HookKey(id,tname) ); + if (ielement == _hooks.end()) { + auto r = _hooks.insert( make_pair( HookKey(id,tname), HookElement(NULL) ) ); + ielement = r.first; + } else { + (*ielement).second.resetFlags( HookElement::OpenRingStart ); + } + current->setNext( &((*ielement).second) ); + } + + + Hook* JsonStack::getHook ( unsigned int jsonId, const std::string& tname ) const + { + auto ihook = _hooks.find( HookKey(jsonId,tname) ); + if (ihook == _hooks.end()) return NULL; + + return (*ihook).second.hook(); + } + + + bool JsonStack::hookFromString ( std::string s, unsigned int& id, std::string& tname ) + { + size_t dot = s.rfind('.'); + if (dot == string::npos) return false; + + tname = s.substr( 0, dot ); + id = stoul( s.substr(dot+1) ); + return true; + } + + + bool JsonStack::checkRings () const + { + bool status = true; + + for ( auto kv : _hooks ) { + HookElement* ringStart = &(kv.second); + if (ringStart->issetFlags(HookElement::ClosedRing)) continue; + + if (ringStart->issetFlags(HookElement::OpenRingStart)) { + cerr << Error( "JsonStack::checkRing(): Open ring found, starting with %s.\n" + " Closing the ring..." + , getString(ringStart->hook()).c_str() ) << endl; + + status = false; + HookElement* element = ringStart; + while ( true ) { + if (not element->next()) { + // The ring is open: close it (loop on ringStart). + element->setNext( ringStart ); + element->setFlags( HookElement::ClosedRing ); + + cerr << Error( "Simple open ring." ) << endl; + break; + } + if (element->next()->issetFlags(HookElement::ClosedRing)) { + // The ring is half merged with itself, or another ring. + // (i.e. *multiple* hooks pointing the *same* next element) + element->setNext( ringStart ); + element->setFlags( HookElement::ClosedRing ); + + cerr << Error( "Complex fault: ring partially merged (convergent)." ) << endl; + break; + } + element = element->next(); + } + } + } + + return status; + } + + + void JsonStack::buildRings () const + { + for ( auto kv : _hooks ) { + kv.second.hook()->_setNextHook( kv.second.next()->hook() ); + } + } + + + void JsonStack::print ( ostream& o ) const + { + o << tab << "JsonStack::print() Stack contains " << _stack.size() << " elements." << endl; + for ( size_t i=0 ; i<_stack.size() ; ++i ) { + o << "[" << right << setw(2) << i << "] key: \"" << left << setw(20) << _stack[i].first + << "\", type: \"" << demangle(_stack[i].second.type()) << "\"." << endl; + } + } + + +// ------------------------------------------------------------------- +// Function : Json Cell parser. + + Cell* jsonCellParse ( string filename ) + { + UpdateSession::open(); + + JsonReader reader ( JsonWriter::CellMode ); + reader.parse( filename ); + + UpdateSession::close(); + + const JsonStack& stack = reader.getStack(); + if (stack.rhas(".Cell")) return stack.as(".Cell"); + + return NULL; + } + + +// ------------------------------------------------------------------- +// Function : Json Blob parser. + + Cell* jsonBlobParse ( string filename ) + { + UpdateSession::open(); + + JsonReader reader ( JsonWriter::DesignBlobMode ); + reader.parse( filename ); + + UpdateSession::close(); + + const JsonStack& stack = reader.getStack(); + if (stack.rhas(".DesignBlob")) { + DesignBlob* blob = stack.as(".DesignBlob"); + Cell* cell = blob->getTopCell(); + delete blob; + return cell; + } + + return NULL; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/JsonWriter.cpp b/hurricane/src/hurricane/JsonWriter.cpp new file mode 100644 index 00000000..a00e28e0 --- /dev/null +++ b/hurricane/src/hurricane/JsonWriter.cpp @@ -0,0 +1,101 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./JsonWriter.cpp" | +// +-----------------------------------------------------------------+ + + +#include "rapidjson/filewritestream.h" +#include "rapidjson/prettywriter.h" +#include "hurricane/Commons.h" + + +//namespace Hurricane { + + typedef rapidjson::PrettyWriter JsonOfstream; + +#define _WRITER reinterpret_cast(_writer) + + +// ------------------------------------------------------------------- +// Class : "JsonWriter". + + JsonWriter::JsonWriter ( std::string fileName ) + : _flags (0) + , _bufferSize(65536) + , _buffer (new char [_bufferSize]) + , _file (NULL) + , _stream (NULL) + , _writer (NULL) + { + _file = fopen( fileName.c_str(), "w" ); + _stream = new rapidjson::FileWriteStream ( _file, _buffer, _bufferSize ); + _writer = new JsonOfstream ( *_stream ); + _WRITER->SetIndent( ' ', 2 ); + } + + + JsonWriter::~JsonWriter () + { close(); } + + + void JsonWriter::close () + { + if (_writer) { delete _WRITER; _writer = NULL; } + if (_stream) { delete _stream; _stream = NULL; } + if (_file ) { fclose(_file); _file = NULL; } + } + + + void JsonWriter::key ( const char* k ) { _WRITER->Key(k); }; + void JsonWriter::key ( std::string k ) { _WRITER->Key(k.c_str()); }; + void JsonWriter::startObject() { _WRITER->StartObject(); }; + void JsonWriter::startArray () { _WRITER->StartArray(); }; + void JsonWriter::endObject () { _WRITER->EndObject(); }; + void JsonWriter::endArray () { _WRITER->EndArray(); }; + void JsonWriter::write () { _WRITER->Null(); }; + void JsonWriter::write ( const char* s ) { _WRITER->String(s); }; + void JsonWriter::write ( const std::string* s ) { _WRITER->String(s->c_str()); }; + void JsonWriter::write ( std::string s ) { _WRITER->String(s.c_str()); }; + void JsonWriter::write ( const bool* v ) { _WRITER->Bool (*v); } + void JsonWriter::write ( bool v ) { _WRITER->Bool ( v); } + void JsonWriter::write ( const int* v ) { _WRITER->Int (*v); } + void JsonWriter::write ( int v ) { _WRITER->Int ( v); } + void JsonWriter::write ( const long* v ) { _WRITER->Int64 (*v); } + void JsonWriter::write ( long v ) { _WRITER->Int64 ( v); } + void JsonWriter::write ( const unsigned int* v ) { _WRITER->Uint (*v); } + void JsonWriter::write ( unsigned int v ) { _WRITER->Uint ( v); } + void JsonWriter::write ( const unsigned long* v ) { _WRITER->Uint64(*v); } + void JsonWriter::write ( unsigned long v ) { _WRITER->Uint64( v); } + JsonWriter* JsonWriter::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + JsonWriter* JsonWriter::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + bool JsonWriter::issetFlags ( unsigned long mask ) const { return _flags & mask; } + unsigned long JsonWriter::getFlags () const { return _flags; } + + + +//} // Hurricane namespace. diff --git a/hurricane/src/hurricane/Layer.cpp b/hurricane/src/hurricane/Layer.cpp index b2eacc8a..5f790eed 100644 --- a/hurricane/src/hurricane/Layer.cpp +++ b/hurricane/src/hurricane/Layer.cpp @@ -219,7 +219,7 @@ namespace Hurricane { } - string Layer::_getString() const + string Layer::_getString () const { string s = DBo::_getString(); s.insert(s.length() - 1, " " + getString(_name)); @@ -227,7 +227,7 @@ namespace Hurricane { } - Record* Layer::_getRecord() const + Record* Layer::_getRecord () const { Record* record = DBo::_getRecord(); if (record) { @@ -242,4 +242,7 @@ namespace Hurricane { } + const Name& Layer::_sgetName ( const Layer* layer ) + { return layer->getName(); } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Library.cpp b/hurricane/src/hurricane/Library.cpp index c348b9be..329c104b 100644 --- a/hurricane/src/hurricane/Library.cpp +++ b/hurricane/src/hurricane/Library.cpp @@ -97,6 +97,19 @@ void Library::setName(const Name& name) } } +string Library::getHierarchicalName () const +// ***************************************** +{ + string rpath; + Library* library = getLibrary(); + do { + rpath.insert( 0, getString(library->getName())+"." ); + + library = library->getLibrary(); + } while ( library ); + + return rpath + getString(getName()); +} void Library::_postCreate() // ************************ { @@ -215,6 +228,70 @@ void Library::CellMap::_setNextElement(Cell* cell, Cell* nextCell) const cell->_setNextOfLibraryCellMap(nextCell); }; +void Library::_toJson(JsonWriter* w) const +// *************************************** +{ + Inherit::_toJson( w ); + + jsonWrite( w, "_name" , getName() ); + jsonWrite( w, "+cellMap" , getCells() ); + jsonWrite( w, "+libraryMap", getLibraries() ); +} + + +// **************************************************************************************************** +// JsonLibrary implementation +// **************************************************************************************************** + +JsonLibrary::JsonLibrary(unsigned long flags) +// ************************************ + : JsonDBo(flags) +{ + add( ".Library" , typeid(Library*) ); + add( "_name" , typeid(string) ); + add( "+cellMap" , typeid(JsonArray) ); + add( "+libraryMap", typeid(JsonArray) ); +} + +string JsonLibrary::getTypeName() const +// ********************************* +{ return "Library"; } + +JsonLibrary* JsonLibrary::clone(unsigned long flags) const +// ************************************************* +{ return new JsonLibrary ( flags ); } + +void JsonLibrary::toData(JsonStack& stack) +// *************************************** +{ + check( stack, "JsonLibrary::toData" ); + + Name libName ( get ( stack, "_name" ) ); + Library* parent = get( stack, ".Library" ); + if (not parent) + parent = get( stack, "_library" ); + + Library* library = NULL; + if (parent) { + library = parent->getLibrary( libName ); + if (not library) + library = Library::create( parent, libName ); + } else { + library = DataBase::getDB()->getRootLibrary(); + if (not library) + library = Library::create( DataBase::getDB(), libName ); + else { + if (library->getName() != libName) { + throw Error( "JsonLibrary::toData(): Root library name discrepency, \"%s\" vs. \"%s\"." + , getString(library->getName()).c_str() + , getString(libName).c_str() + ); + } + } + } + + update( stack, library ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index 56e75993..3bf41410 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -738,6 +738,37 @@ Record* Net::_getRecord() const return record; } +void Net::_toJson(JsonWriter* writer) const +// **************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_name" , getName() ); + jsonWrite( writer, "_isGlobal" , isGlobal() ); + jsonWrite( writer, "_isExternal" , isExternal() ); + jsonWrite( writer, "_isAutomatic" , isAutomatic() ); + jsonWrite( writer, "_type" , getString(getType()) ); + jsonWrite( writer, "_direction" , getString(getDirection()) ); +} + +void Net::_toJsonSignature(JsonWriter* writer) const +// ************************************************* +{ + jsonWrite( writer, "_name", getName() ); +} + +void Net::_toJsonCollections(JsonWriter* writer) const +// *************************************************** +{ + jsonWrite( writer, "+aliases", getAliases() ); + writer->setFlags( JsonWriter::UsePlugReference ); + jsonWrite( writer, "+componentSet", getComponents() ); + writer->resetFlags( JsonWriter::UsePlugReference ); + + Inherit::_toJsonCollections( writer ); +} + + // **************************************************************************************************** // Net::Type implementation // **************************************************************************************************** @@ -745,13 +776,22 @@ Record* Net::_getRecord() const Net::Type::Type(const Code& code) // ****************************** : _code(code) -{ -} +{ } Net::Type::Type(const Type& type) // ****************************** : _code(type._code) +{ } + +Net::Type::Type(string s) +// ********************** +: _code(UNDEFINED) { + if (s == "UNDEFINED") _code = UNDEFINED; + else if (s == "LOGICAL" ) _code = LOGICAL; + else if (s == "CLOCK" ) _code = CLOCK; + else if (s == "POWER" ) _code = POWER; + else if (s == "GROUND" ) _code = GROUND; } Net::Type& Net::Type::operator=(const Type& type) @@ -784,13 +824,23 @@ Record* Net::Type::_getRecord() const Net::Direction::Direction(const Code& code) // **************************************** : _code(code) -{ -} +{ } Net::Direction::Direction(const Direction& direction) // ************************************************** : _code(direction._code) +{ } + +Net::Direction::Direction(string s) +// ******************************** +: _code(UNDEFINED) { + if (s.size() > 3) { + if (s[0] == 'i') *this |= DirIn; + if (s[0] == 'o') *this |= DirOut; + if (s[0] == 't') *this |= ConnTristate; + if (s[0] == 'w') *this |= ConnWiredOr; + } } Net::Direction& Net::Direction::operator=(const Direction& direction) @@ -1008,6 +1058,81 @@ string Net_SlavePlugs::Locator::_getString() const return s; } + + +// **************************************************************************************************** +// JsonNet implementation +// **************************************************************************************************** + +JsonNet::JsonNet(unsigned long flags) +// ********************************** + : JsonEntity (flags) + , _autoMaterialize(not Go::autoMaterializationIsDisabled()) + , _net (NULL) + , _stack (NULL) +{ + if (flags & JsonWriter::RegisterMode) return; + + ltrace(51) << "JsonNet::JsonNet()" << endl; + + add( "_name" , typeid(string) ); + add( "_isGlobal" , typeid(bool) ); + add( "_isExternal" , typeid(bool) ); + add( "_isAutomatic" , typeid(bool) ); + add( "_type" , typeid(string) ); + add( "_direction" , typeid(string) ); + add( "+aliases" , typeid(JsonArray) ); + add( "+componentSet", typeid(JsonArray) ); + + ltrace(51) << "Disabling auto-materialization (" << _autoMaterialize << ")." << endl; + Go::disableAutoMaterialization(); +} + +JsonNet::~JsonNet() +// **************** +{ + _stack->checkRings(); + _stack->buildRings(); + _stack->clearHookLinks(); + + _net->materialize(); + + if (_autoMaterialize) { + Go::enableAutoMaterialization(); + ltrace(51) << "Enabling auto-materialization." << endl; + } +} + +string JsonNet::getTypeName() const +// ********************************* +{ return "Net"; } + +JsonNet* JsonNet::clone(unsigned long flags) const +// *********************************************** +{ return new JsonNet ( flags ); } + +void JsonNet::toData(JsonStack& stack) +// *********************************** +{ + ltracein(51); + + _stack = &stack; + + check( stack, "JsonNet::toData" ); + presetId( stack ); + + _net = Net::create( get(stack,".Cell") , get(stack,"_name") ); + _net->setGlobal ( get(stack,"_isGlobal" ) ); + _net->setExternal ( get(stack,"_isExternal" ) ); + _net->setAutomatic( get(stack,"_isAutomatic") ); + _net->setType ( Net::Type (get(stack,"_type")) ); + _net->setDirection( Net::Direction(get(stack,"_direction")) ); + + update( stack, _net ); + + ltraceout(51); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Occurrence.cpp b/hurricane/src/hurricane/Occurrence.cpp index 077a2969..f3201ffd 100644 --- a/hurricane/src/hurricane/Occurrence.cpp +++ b/hurricane/src/hurricane/Occurrence.cpp @@ -261,6 +261,23 @@ string Occurrence::getCompactString() const return s; } +void Occurrence::toJson(JsonWriter* w) const +// ****************************************** +{ + w->startObject(); + jsonWrite( w, "@typename", "Occurrence" ); + jsonWrite( w, "_path" , getPath().getJsonString(w->getFlags()) ); + + w->key( "_entity" ); + if (not w->issetFlags(JsonWriter::DesignBlobMode)) { + getEntity()->toJsonSignature( w ); + } else { + jsonWrite( w, getEntity()->getId() ); + } + + w->endObject(); +} + Record* Occurrence::_getRecord() const // **************************** { @@ -307,6 +324,77 @@ string Occurrence::getName() const return description; } +JsonOccurrence::JsonOccurrence(unsigned long flags) +// ************************************************ + : JsonObject(flags) +{ + add( ".Cell" , typeid(Cell*) ); + add( "_path" , typeid(string) ); + + if (issetFlags(JsonWriter::DesignBlobMode)) { + add( "_entity", typeid(uint64_t) ); + } else { + add( "_entity", typeid(Entity*) ); + } +} + +JsonOccurrence* JsonOccurrence::clone(unsigned long flags) const +// ************************************************************* +{ return new JsonOccurrence ( flags ); } + +string JsonOccurrence::getTypeName() const +// *************************************** +{ return "Occurrence"; } + +void JsonOccurrence::toData(JsonStack& stack) +// ****************************************** +{ + check( stack, "JsonOccurrence::toData" ); + + Path path; + Entity* entity = NULL; + if (issetFlags(JsonWriter::DesignBlobMode)) { + entity = stack.getEntity( get(stack,"_entity") ); + + //Cell* cell = get( stack, ".Cell" ); + Instance* instance = NULL; + char separator = SharedPath::getNameSeparator(); + string pathIds = get( stack, "_path" ); + unsigned long id; + size_t dot = pathIds.find( separator ); + + if (dot != string::npos) { + id = stoul( pathIds.substr( 0, dot ) ); + pathIds = pathIds.substr( dot+1 ); + } else + id = stol( pathIds ); + + instance = stack.getEntity(id); + if (not instance) + throw Error( "JsonOccurrence::toData(): No Instance id:lu% (or not an Instance) in stack LUT.", id ); + path = Path( instance ); + + while ( dot != string::npos ) { + dot = pathIds.find( separator ); + if (dot != string::npos) { + id = stoul( pathIds.substr( 0, dot ) ); + pathIds = pathIds.substr( dot+1 ); + } else + id = stol( pathIds ); + + instance = stack.getEntity(id); + if (not instance) + throw Error( "JsonOccurrence::toData(): No Instance id:lu% (or not an Instance) in stack LUT.", id ); + path = Path( path, instance ); + } + } else { + entity = get(stack,"_entity"); + path = Path( get(stack,".Cell"), get(stack,"_path") ); + } + + Occurrence occurrence ( entity, path ); + update( stack, occurrence ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Pad.cpp b/hurricane/src/hurricane/Pad.cpp index 2ad7aa36..7c23d9e9 100644 --- a/hurricane/src/hurricane/Pad.cpp +++ b/hurricane/src/hurricane/Pad.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Pad.h" #include "hurricane/Net.h" #include "hurricane/BasicLayer.h" @@ -117,6 +119,15 @@ void Pad::setBoundingBox(const Box& boundingBox) } } +void Pad::_toJson(JsonWriter* writer) const +// **************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_layer" , _layer->getName() ); + jsonWrite( writer, "_boundingBox", &_boundingBox ); +} + string Pad::_getString() const // *************************** { @@ -137,6 +148,45 @@ Record* Pad::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonPad implementation +// **************************************************************************************************** + +JsonPad::JsonPad(unsigned long flags) +// ********************************** + : JsonComponent(flags) +{ + add( "_layer" , typeid(string) ); + add( "_boundingBox", typeid(Box) ); +} + +string JsonPad::getTypeName() const +// ******************************** +{ return "Pad"; } + +JsonPad* JsonPad::clone(unsigned long flags) const +// *********************************************** +{ return new JsonPad ( flags ); } + +void JsonPad::toData(JsonStack& stack) +// *********************************** +{ + check( stack, "JsonPad::toData" ); + unsigned int jsonId = presetId( stack ); + + Pad* pad = Pad::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , get(stack,".Box") + ); + + stack.addHookLink( pad->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, pad ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Path.cpp b/hurricane/src/hurricane/Path.cpp index 36a17c38..49a35b4f 100644 --- a/hurricane/src/hurricane/Path.cpp +++ b/hurricane/src/hurricane/Path.cpp @@ -258,6 +258,25 @@ string Path::getCompactString() const return s; } +string Path::getJsonString(unsigned long flags) const +// ************************************************** +{ + if (isEmpty()) return ""; + + string s; + if (flags & JsonWriter::DesignBlobMode) { + //s += getString(getOwnerCell()->getId()) + "::"; + s += getString(_sharedPath->getJsonString(flags)); + //s += "::" + getString(getMasterCell()->getId()); + } else { + //s += getString(getOwnerCell()->getName()) + "::"; + s += getString(_sharedPath->getJsonString(flags)); + //s += "::" + getString(getMasterCell()->getName()); + } + + return s; +} + string Path::_getString() const // **************************** { @@ -282,7 +301,6 @@ Record* Path::_getRecord() const } - } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Plug.cpp b/hurricane/src/hurricane/Plug.cpp index e65a2c5a..6027c3de 100644 --- a/hurricane/src/hurricane/Plug.cpp +++ b/hurricane/src/hurricane/Plug.cpp @@ -153,11 +153,12 @@ void Plug::setNet(Net* net) Plug* Plug::_create(Instance* instance, Net* masterNet) // **************************************************** { - Plug* plug = new Plug(instance, masterNet); + if (Entity::inForcedIdMode()) Entity::setNextId( 0 ); - plug->_postCreate(); + Plug* plug = new Plug(instance, masterNet); - return plug; + plug->_postCreate(); + return plug; } void Plug::_postCreate() @@ -190,6 +191,18 @@ void Plug::_preDestroy() // trace_out(); } +void Plug::_toJson(JsonWriter* writer) const +// ***************************************** +{ + if (writer->issetFlags(JsonWriter::UsePlugReference)) { + jsonWrite( writer, "_id" , getId() ); + jsonWrite( writer, "_instance", getInstance()->getName() ); + } else { + Inherit::_toJson( writer ); + jsonWrite( writer, "_masterNet", getMasterNet()->getName() ); + } +} + string Plug::_getString() const // **************************** { @@ -217,6 +230,109 @@ string Plug::getName() const + getString(_masterNet->getName()); } + + +// **************************************************************************************************** +// JsonPlug implementation +// **************************************************************************************************** + +JsonPlug::JsonPlug(unsigned long flags) +// ************************************ + : JsonComponent(flags) +{ + add( "_masterNet", typeid(string) ); +} + +string JsonPlug::getTypeName() const +// ********************************* +{ return "Plug"; } + +JsonPlug* JsonPlug::clone(unsigned long flags) const +// ************************************************* +{ return new JsonPlug ( flags ); } + +void JsonPlug::toData(JsonStack& stack) +// ************************************ +{ +// We are parsing an Instance. +// Plugs are automatically createds whith the Instance. +// Here we add the Plug to the stack's entity table that +// associates the Json Ids to the actual Hurricane ones. +// At the same time, we perform some coherency checking +// (i.e. the same Plug already exists). + +// For now, simply discard "_id" & "_propertySet". + check( stack, "JsonPlug::toData" ); + + Instance* instance = get(stack,".Instance"); + Plug* plug = NULL; + if (instance) { + Net* masterNet = instance->getMasterCell()->getNet( get(stack,"_masterNet") ); + if (not masterNet) { + cerr << Error( "JsonPlug::toData(): Incoherency, instance %s master doesn't containt net %s." + , getString(instance->getName()).c_str() + , get(stack,"_masterNet").c_str() + ) << endl; + } else { + unsigned int jsonId = get(stack,"_id"); + plug = instance->getPlug( masterNet ); + if (issetFlags(JsonWriter::DesignBlobMode)) + plug->forceId( jsonId ); + stack.addHookLink( plug->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + } + } else { + cerr << Error( "JsonPlug::toData(): Cannot find \".Instance\" in stack, skipping." ) << endl; + } + ltrace(51) << "Instance Plug contents ignored for now." << endl; + + update( stack, plug ); +} + + + +// **************************************************************************************************** +// JsonPlugRef implementation +// **************************************************************************************************** + +JsonPlugRef::JsonPlugRef(unsigned long flags) +// ****************************************** + : JsonObject(flags) +{ + add( ".Net" , typeid(Net*) ); + add( "_id" , typeid(uint64_t) ); + add( "_instance", typeid(string) ); +} + +string JsonPlugRef::getTypeName() const +// ************************************ +{ return "&Plug"; } + +JsonPlugRef* JsonPlugRef::clone(unsigned long flags) const +// ******************************************************* +{ return new JsonPlugRef ( flags ); } + +void JsonPlugRef::toData(JsonStack& stack) +// *************************************** +{ + check( stack, "JsonPlugRef::toData" ); + +// We are parsing a Net, perform only a "Plug::setNet()". + Net* net = get(stack,".Net"); + Instance* instance = net->getCell()->getInstance( get(stack,"_instance") ); + unsigned int id = get(stack,"_id"); + + Plug* plug = stack.getEntity(id); + if (plug) { + plug->setNet( net ); + } else { + cerr << Error( "JsonPlugRef::toData(): No Plug id:%u in instance %s, while building net %s." + , id, getString(instance->getName()).c_str(), getString(net->getName()).c_str() + ) << endl; + } + + update( stack, plug ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Point.cpp b/hurricane/src/hurricane/Point.cpp index 902dee17..7f6f5a05 100644 --- a/hurricane/src/hurricane/Point.cpp +++ b/hurricane/src/hurricane/Point.cpp @@ -123,7 +123,40 @@ Record* Point::_getRecord() const return record; } +void Point::toJson ( JsonWriter* w ) const +// **************************************** +{ + w->startObject(); + jsonWrite( w, "@typename", "Point" ); + jsonWrite( w, "_x", getX() ); + jsonWrite( w, "_y", getY() ); + w->endObject(); +} +JsonPoint::JsonPoint(unsigned long flags) +// ************************************** + : JsonObject(flags) +{ + add( "_x", typeid(int64_t) ); + add( "_y", typeid(int64_t) ); +} + +JsonPoint* JsonPoint::clone(unsigned long flags) const +// *************************************************** +{ return new JsonPoint ( flags ); } + +string JsonPoint::getTypeName() const +// ********************************** +{ return "Point"; } + +void JsonPoint::toData(JsonStack& stack) +// ************************************* +{ + check( stack, "JsonPoint::toData" ); + Point point ( DbU::fromDb(get(stack,"_x")) + , DbU::fromDb(get(stack,"_y")) ); + update( stack, point ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/RoutingPad.cpp b/hurricane/src/hurricane/RoutingPad.cpp index 91b18cc8..81465ada 100644 --- a/hurricane/src/hurricane/RoutingPad.cpp +++ b/hurricane/src/hurricane/RoutingPad.cpp @@ -38,6 +38,7 @@ #include "hurricane/Segment.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" +#include "hurricane/Pad.h" #include "hurricane/Cell.h" #include "hurricane/Instance.h" #include "hurricane/Warning.h" @@ -50,6 +51,9 @@ namespace Hurricane { using std::ostringstream; +// ------------------------------------------------------------------- +// Class : "RoutingPad". + RoutingPad::RoutingPad ( Net* net, Occurrence occurrence ) : Inherit (net) , _occurrence(occurrence) @@ -61,18 +65,27 @@ namespace Hurricane { if ( not net ) throw Error ("Can't create RoutingPad : NULL net"); if ( not occurrence.isValid() ) throw Error ("Can't create RoutingPag : Invalid occurrence"); - Plug* plug = NULL; - Pin* pin = NULL; - Contact* contact = NULL; + Plug* plug = NULL; + Pin* pin = NULL; + Contact* contact = NULL; + Horizontal* horizontal = NULL; + Vertical* vertical = NULL; + Pad* pad = NULL; if ( (plug = dynamic_cast(occurrence.getEntity()) ) == NULL) { if ( (pin = dynamic_cast(occurrence.getEntity()) ) == NULL) { - contact = dynamic_cast(occurrence.getEntity()); + if ( (contact = dynamic_cast(occurrence.getEntity()) ) == NULL) { + if ( (horizontal = dynamic_cast(occurrence.getEntity()) ) == NULL) { + if ( (vertical = dynamic_cast(occurrence.getEntity()) ) == NULL) { + pad = dynamic_cast(occurrence.getEntity()); + } + } + } } } - if ( (not plug) and (not pin) and (not contact) ) - throw Error ("Can't create RoutingPad : Plug, Pin, or Contact Occurrence *required*"); + if ( (not plug) and (not pin) and (not contact) and (not horizontal) and (not vertical) and (not pad) ) + throw Error ("Can't create RoutingPad : Plug, Pin, Contact, Horizontal, Vertical or Pad Occurrence *required*"); RoutingPad* routingPad = new RoutingPad( net, occurrence ); routingPad->_postCreate(); @@ -156,8 +169,9 @@ namespace Hurricane { Box RoutingPad::getBoundingBox ( const BasicLayer* basicLayer ) const { Component* component = _getEntityAsComponent(); - if ( component ) + if ( component ) { return _occurrence.getPath().getTransformation().getBox ( component->getBoundingBox(basicLayer) ); + } return Box(getPosition()); } @@ -175,8 +189,9 @@ namespace Hurricane { Point RoutingPad::getPosition () const { Component* component = _getEntityAsComponent(); - if (component) + if (component) { return _occurrence.getPath().getTransformation().getPoint( component->getCenter() ); + } return Point(); } @@ -233,6 +248,12 @@ namespace Hurricane { } + void RoutingPad::_toJson ( JsonWriter* writer ) const + { + Inherit::_toJson( writer ); + jsonWrite( writer, "_occurrence", &_occurrence ); + } + string RoutingPad::_getString () const { string s = Inherit::_getString(); @@ -379,4 +400,37 @@ namespace Hurricane { } +// ------------------------------------------------------------------- +// Class : "JsonRoutingPad". + + JsonRoutingPad::JsonRoutingPad ( unsigned long flags ) + : JsonComponent(flags) + { + add( "_occurrence", typeid(Occurrence) ); + } + + string JsonRoutingPad::getTypeName () const + { return "RoutingPad"; } + + + JsonRoutingPad* JsonRoutingPad::clone ( unsigned long flags ) const + { return new JsonRoutingPad ( flags ); } + + + void JsonRoutingPad::toData ( JsonStack& stack ) + { + check( stack, "JsonRoutingPad::toData" ); + unsigned int jsonId = presetId( stack ); + + RoutingPad* rp = RoutingPad::create + ( get (stack,".Net") + , get(stack,"_occurrence") + ); + + stack.addHookLink( rp->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + + update( stack, rp ); + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Segment.cpp b/hurricane/src/hurricane/Segment.cpp index 1eba7e0c..9635d86b 100644 --- a/hurricane/src/hurricane/Segment.cpp +++ b/hurricane/src/hurricane/Segment.cpp @@ -306,6 +306,17 @@ void Segment::_preDestroy() // trace_out(); } +void Segment::_toJson(JsonWriter* writer) const +// ******************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_sourceHook", _sourceHook.getNextHook()->toJson() ); + jsonWrite( writer, "_targetHook", _targetHook.getNextHook()->toJson() ); + jsonWrite( writer, "_layer" , _layer->getName() ); + jsonWrite( writer, "_width" , _width ); +} + string Segment::_getString() const // ******************************* { @@ -318,7 +329,7 @@ string Segment::_getString() const } Record* Segment::_getRecord() const -// ************************** +// ******************************** { Record* record = Inherit::_getRecord(); if (record) { @@ -332,6 +343,7 @@ Record* Segment::_getRecord() const return record; } + // **************************************************************************************************** // Segment::SourceHook implementation // **************************************************************************************************** @@ -342,11 +354,13 @@ Segment::SourceHook::SourceHook(Segment* segment) // ********************************************** : Inherit() { - if (!segment) - throw Error("Can't create " + _TName("Segment::SourceHook") + " (null segment)"); + if (!segment) + throw Error("Can't create " + _getTypeName() + " (null segment)"); - if (SOURCE_HOOK_OFFSET == -1) - SOURCE_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + if (SOURCE_HOOK_OFFSET == -1) { + SOURCE_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Segment::SourceHook::getComponent() const @@ -361,6 +375,16 @@ string Segment::SourceHook::_getString() const return "<" + _TName("Segment::SourceHook") + " " + getString(getComponent()) + ">"; } +Hook* Segment::SourceHook::_compToHook(Component* component) +// *************************************************************** +{ + Segment* segment = dynamic_cast(component); + if (not segment) { + throw Error( "SourceHook::_compToHook(): Unable to cast %s into Segment*." + , getString(component).c_str() ); + } + return &(segment->_sourceHook); +} // **************************************************************************************************** @@ -376,8 +400,10 @@ Segment::TargetHook::TargetHook(Segment* segment) if (!segment) throw Error("Can't create " + _TName("Segment::TargetHook") + " (null segment)"); - if (TARGET_HOOK_OFFSET == -1) - TARGET_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + if (TARGET_HOOK_OFFSET == -1) { + TARGET_HOOK_OFFSET = (unsigned long)this - (unsigned long)segment; + Hook::addCompToHook(_getTypeName(),_compToHook); + } } Component* Segment::TargetHook::getComponent() const @@ -392,6 +418,18 @@ string Segment::TargetHook::_getString() const return "<" + _TName("Segment::TargetHook") + " " + getString(getComponent()) + ">"; } +Hook* Segment::TargetHook::_compToHook(Component* component) +// *************************************************************** +{ + Segment* segment = dynamic_cast(component); + if (not segment) { + throw Error( "TargetHook::_compToHook(): Unable to cast %s into Segment*." + , getString(component).c_str() ); + } + return &(segment->_targetHook); +} + + // **************************************************************************************************** // Segment_Hooks implementation // **************************************************************************************************** @@ -633,6 +671,20 @@ string Segment_Anchors::Locator::_getString() const +// **************************************************************************************************** +// JsonSegment implementation +// **************************************************************************************************** + +JsonSegment::JsonSegment(unsigned long flags) +// ****************************************** + : JsonComponent(flags) +{ + add( "_sourceHook", typeid(string) ); + add( "_targetHook", typeid(string) ); + add( "_layer" , typeid(uint64_t) ); + add( "_width" , typeid(uint64_t) ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/SharedPath.cpp b/hurricane/src/hurricane/SharedPath.cpp index 04d83f7e..a0a97575 100644 --- a/hurricane/src/hurricane/SharedPath.cpp +++ b/hurricane/src/hurricane/SharedPath.cpp @@ -186,6 +186,23 @@ string SharedPath::getName() const return name; } +string SharedPath::getJsonString(unsigned long flags) const +// ******************************************************** +{ + string name = ""; + SharedPath* sharedPath = (SharedPath*)this; + while (sharedPath) { + if (flags & JsonWriter::DesignBlobMode) + name += getString(sharedPath->getHeadInstance()->getId()); + else + name += getString(sharedPath->getHeadInstance()->getName()); + + sharedPath = sharedPath->getTailSharedPath(); + if (sharedPath) name += getNameSeparator(); + } + return name; +} + Cell* SharedPath::getOwnerCell() const // *********************************** { diff --git a/hurricane/src/hurricane/Signature.cpp b/hurricane/src/hurricane/Signature.cpp new file mode 100644 index 00000000..cbc1dc27 --- /dev/null +++ b/hurricane/src/hurricane/Signature.cpp @@ -0,0 +1,167 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Authors : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Signature.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Path.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" +#include "hurricane/Signature.h" + + +namespace Hurricane { + + using std::ostringstream; + + +// ------------------------------------------------------------------- +// Class : "Signature". + + void Signature::setLayer ( const std::string& layer ) + { + _layer = DataBase::getDB()->getTechnology()->getLayer( layer ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonSignature". + + JsonSignature::JsonSignature ( unsigned long flags ) + : JsonObject (flags) + , _subTypeName("unset") + { } + + string JsonSignature::getTypeName () const + { return "Signature"; } + + + void JsonSignature::setSubType ( const std::string& subTypeName ) + { + clear(); + _subTypeName = subTypeName; + + if (_subTypeName == "Instance") { + add( "_instance" , typeid(string) ); + } else if (_subTypeName == "Net") { + add( "_name", typeid(string) ); + } else if (_subTypeName == "Plug") { + add( "_masterNet", typeid(string) ); + } else if (_subTypeName == "Contact") { + add( "_net", typeid(string) ); + JsonContact jobject (0); + copyAttrs( &jobject ); + } else if (_subTypeName == "Vertical") { + add( "_net", typeid(string) ); + JsonVertical jobject (0); + copyAttrs( &jobject ); + } else if (_subTypeName == "Horizontal") { + add( "_net", typeid(string) ); + JsonHorizontal jobject (0); + copyAttrs( &jobject ); + } + } + + JsonSignature* JsonSignature::clone ( unsigned long flags ) const + { return new JsonSignature ( flags ); } + + + void JsonSignature::toData ( JsonStack& stack ) + { + ltrace(51) << (void*)this << " _subTypeName:" << _subTypeName << endl; + + check( stack, "JsonSignature::toData" ); + + Cell* ownerCell = get ( stack, ".Cell" ); + string pathName = get( stack, "_path" ); + Path path ( ownerCell, pathName ); + Cell* masterCell = path.getMasterCell(); + Entity* entity = NULL; + + if (_subTypeName == "Instance") { + entity = masterCell->getInstance( get(stack,"_name") ); + } else if (_subTypeName == "Net") { + entity = masterCell->getNet( get(stack,"_name") ); + } else if (_subTypeName == "Plug") { + Net* masterNet = masterCell->getNet( get(stack,"_masterNet") ); + entity = path.getTailInstance()->getPlug( masterNet ); + } else if (_subTypeName == "Contact") { + Signature signature; + signature.setType ( Signature::TypeContact ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer" ) ); + signature.setDim( Signature::ContactDx , get(stack,"_dx" ) ); + signature.setDim( Signature::ContactDy , get(stack,"_dy" ) ); + signature.setDim( Signature::ContactWidth , get(stack,"_width" ) ); + signature.setDim( Signature::ContactHeight, get(stack,"_height") ); + entity = masterCell->getEntity( signature ); + } else if (_subTypeName == "Vertical") { + Signature signature; + signature.setType ( Signature::TypeVertical ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer") ); + signature.setDim( Signature::VerticalWidth , get(stack,"_width" ) ); + signature.setDim( Signature::VerticalX , get(stack,"_x" ) ); + signature.setDim( Signature::VerticalDySource, get(stack,"_dySource") ); + signature.setDim( Signature::VerticalDyTarget, get(stack,"_dyTarget") ); + entity = masterCell->getEntity( signature ); + } else if (_subTypeName == "Horizontal") { + Signature signature; + signature.setType ( Signature::TypeHorizontal ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer") ); + signature.setDim( Signature::HorizontalWidth , get(stack,"_width" ) ); + signature.setDim( Signature::HorizontalY , get(stack,"_y" ) ); + signature.setDim( Signature::HorizontalDxSource, get(stack,"_dxSource") ); + signature.setDim( Signature::HorizontalDxTarget, get(stack,"_dxTarget") ); + entity = masterCell->getEntity( signature ); + } else if (_subTypeName == "Pad") { + Signature signature; + signature.setType ( Signature::TypePad ); + signature.setName ( get(stack,"_net" ) ); + signature.setLayer( get(stack,"_layer") ); + Box bb = get(stack, "_boundingBox" ); + signature.setDim( Signature::PadXMin, bb.getXMin() ); + signature.setDim( Signature::PadYMin, bb.getYMin() ); + signature.setDim( Signature::PadXMax, bb.getXMax() ); + signature.setDim( Signature::PadYMax, bb.getYMax() ); + entity = masterCell->getEntity( signature ); + } + + update( stack, entity ); + } + + +} // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Tabulation.cpp b/hurricane/src/hurricane/Tabulation.cpp index 39a0ac42..c491fe0c 100644 --- a/hurricane/src/hurricane/Tabulation.cpp +++ b/hurricane/src/hurricane/Tabulation.cpp @@ -17,7 +17,8 @@ // not, see . // **************************************************************************************************** -#include "hurricane/Tabulation.h" + +#include "hurricane/Commons.h" namespace Hurricane { diff --git a/hurricane/src/hurricane/Transformation.cpp b/hurricane/src/hurricane/Transformation.cpp index fd83a29a..904779e0 100644 --- a/hurricane/src/hurricane/Transformation.cpp +++ b/hurricane/src/hurricane/Transformation.cpp @@ -255,6 +255,16 @@ Record* Transformation::_getRecord() const return record; } +void Transformation::toJson ( JsonWriter* w ) const +// ************************************************* +{ + w->startObject(); + jsonWrite( w, "@typename", "Transformation" ); + jsonWrite( w, "_tx", getTx() ); + jsonWrite( w, "_ty", getTy() ); + jsonWrite( w, "_orientation", getString( &(getOrientation().getCode()) ) ); + w->endObject(); +} // **************************************************************************************************** @@ -273,6 +283,20 @@ Transformation::Orientation::Orientation(const Orientation& orientation) { } +Transformation::Orientation::Orientation(const string& s) +// ****************************************************** +: _code(ID) +{ + if (s == "ID") _code = ID; + else if (s == "R1") _code = R1; + else if (s == "R2") _code = R2; + else if (s == "R3") _code = R3; + else if (s == "MX") _code = MX; + else if (s == "XR") _code = XR; + else if (s == "MY") _code = MY; + else if (s == "YR") _code = YR; +} + Transformation::Orientation& Transformation::Orientation::operator=(const Orientation& orientation) // ************************************************************************************************ { @@ -295,6 +319,38 @@ Record* Transformation::Orientation::_getRecord() const } +// **************************************************************************************************** +// Transformation::Orientation implementation +// **************************************************************************************************** + +JsonTransformation::JsonTransformation(unsigned long flags) +// ******************************************************** + : JsonObject(flags) +{ + add( "_tx" , typeid(int64_t) ); + add( "_ty" , typeid(int64_t) ); + add( "_orientation", typeid(string) ); +} + +string JsonTransformation::getTypeName() const +// ******************************************* +{ return "Transformation"; } + +JsonTransformation* JsonTransformation::clone(unsigned long flags) const +// ********************************************************************* +{ return new JsonTransformation ( flags ); } + +void JsonTransformation::toData(JsonStack& stack) +// ********************************************** +{ + check( stack, "JsonTransformation::toData" ); + + Transformation transf ( get(stack,"_tx") + , get(stack,"_ty") + , Transformation::Orientation(get(stack,"_orientation")) ); + + update( stack, transf ); +} } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/Vertical.cpp b/hurricane/src/hurricane/Vertical.cpp index 8a0b0948..e34b14eb 100644 --- a/hurricane/src/hurricane/Vertical.cpp +++ b/hurricane/src/hurricane/Vertical.cpp @@ -17,6 +17,8 @@ // not, see . // **************************************************************************************************** +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" #include "hurricane/Vertical.h" #include "hurricane/Layer.h" #include "hurricane/BasicLayer.h" @@ -176,6 +178,16 @@ void Vertical::translate(const DbU::Unit& dx) } } +void Vertical::_toJson(JsonWriter* writer) const +// ******************************************** +{ + Inherit::_toJson( writer ); + + jsonWrite( writer, "_x" , _x ); + jsonWrite( writer, "_dySource", _dySource ); + jsonWrite( writer, "_dyTarget", _dyTarget ); +} + string Vertical::_getString() const // ******************************** { @@ -194,6 +206,51 @@ Record* Vertical::_getRecord() const return record; } + +// **************************************************************************************************** +// JsonVertical implementation +// **************************************************************************************************** + +JsonVertical::JsonVertical(unsigned long flags) +// ******************************************** + : JsonSegment(flags) +{ + add( "_x" , typeid(uint64_t) ); + add( "_dySource", typeid(uint64_t) ); + add( "_dyTarget", typeid(uint64_t) ); +} + +string JsonVertical::getTypeName() const +// ************************************* +{ return "Vertical"; } + +JsonVertical* JsonVertical::clone(unsigned long flags) const +// ********************************************************* +{ return new JsonVertical ( flags ); } + +void JsonVertical::toData(JsonStack& stack) +// **************************************** +{ + check( stack, "JsonVertical::toData" ); + unsigned int jsonId = presetId( stack ); + + Vertical* vertical = Vertical::create + ( get(stack,".Net") + , DataBase::getDB()->getTechnology()->getLayer( get(stack,"_layer") ) + , DbU::fromDb( get(stack,"_x" ) ) + , DbU::fromDb( get(stack,"_width" ) ) + , DbU::fromDb( get(stack,"_dySource") ) + , DbU::fromDb( get(stack,"_dyTarget") ) + ); + + stack.addHookLink( vertical->getBodyHook (), jsonId, get(stack,"_bodyHook" ) ); + stack.addHookLink( vertical->getSourceHook(), jsonId, get(stack,"_sourceHook") ); + stack.addHookLink( vertical->getTargetHook(), jsonId, get(stack,"_targetHook") ); + +// Hook/Ring rebuild are done as a post-process. + update( stack, vertical ); +} + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/grenier/json/DBo.cpp b/hurricane/src/hurricane/grenier/json/DBo.cpp new file mode 100644 index 00000000..1302dc93 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/DBo.cpp @@ -0,0 +1,198 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Remy Escassut | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./DBo.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/Property.h" +#include "hurricane/DBo.h" +#include "hurricane/Quark.h" +#include "hurricane/Error.h" + + +namespace Hurricane { + + +// ------------------------------------------------------------------- +// Class : "Hurricane::DBo". + + + DBo::DBo (): _propertySet() + { } + + + DBo::~DBo () + { } + + + void DBo::_postCreate () + { } + + + void DBo::_preDestroy () + { + clearProperties (); + } + + + void DBo::destroy () + { + _preDestroy(); + + delete this; + } + + + Property* DBo::getProperty ( const Name& name ) const + { + set::const_iterator iterator = _propertySet.begin(); + while ( iterator != _propertySet.end() ) { + Property* property = *iterator; + if (property->getName() == name) return property; + ++iterator; + } + return NULL; + } + + + Properties DBo::getProperties () const + { + return getCollection(_propertySet); + } + + + void DBo::put ( Property* property ) + { + if ( !property ) + throw Error("DBo::put(): Can't put property : NULL property."); + + Property* oldProperty = getProperty ( property->getName() ); + if ( property != oldProperty ) { + if ( oldProperty ) { + _propertySet.erase ( oldProperty ); + oldProperty->onReleasedBy ( this ); + } + _propertySet.insert ( property ); + property->onCapturedBy ( this ); + } + } + + + void DBo::remove ( Property* property ) + { + if ( !property ) + throw Error("DBo::remove(): Can't remove property : NULL property."); + + if ( _propertySet.find(property) != _propertySet.end() ) { + _propertySet.erase ( property ); + property->onReleasedBy ( this ); + if ( dynamic_cast(this) && _propertySet.empty() ) + destroy(); + } + } + + + void DBo::removeProperty ( const Name& name ) + { + Property* property = getProperty ( name ); + if ( property ) { + _propertySet.erase ( property ); + property->onReleasedBy ( this ); + if ( dynamic_cast(this) && _propertySet.empty() ) + destroy(); + } + } + + + void DBo::_onDestroyed ( Property* property ) + { + if ( property && ( _propertySet.find(property) != _propertySet.end() ) ) { + _propertySet.erase ( property ); + if ( dynamic_cast(this) && _propertySet.empty() ) + destroy(); + } + } + + + void DBo::clearProperties () + { + while ( !_propertySet.empty() ) { + Property* property = *_propertySet.begin(); + _propertySet.erase ( property ); + property->onReleasedBy ( this ); + } + } + + + void DBo::_toJson ( JsonWriter* writer ) const + { + // writer->key( "+propertySet" ); + // writer->startArray(); + // writer->endArray(); + } + + + void DBo::_toJsonProperties ( JsonWriter* writer ) const + { + writer->key( "+propertySet" ); + writer->startArray(); + writer->endArray(); + } + + + string DBo::_getTypeName () const + { + return "DBo"; + } + + + string DBo::_getString () const + { + return "<" + _getTypeName() + ">"; + } + + + Record* DBo::_getRecord () const + { + Record* record = new Record ( getString(this) ); + record->add ( getSlot("_propertySet", &_propertySet) ); + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + + JsonDBo::JsonDBo ( unsigned long flags ) + : JsonObject() + { + add( "+propertySet", &DBo::getProperties ); + } + + +} // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/grenier/json/DBo.h b/hurricane/src/hurricane/grenier/json/DBo.h new file mode 100644 index 00000000..01edbabd --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/DBo.h @@ -0,0 +1,114 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Remy Escassut | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/DBo.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_DBO_H +#define HURRICANE_DBO_H + +#include "hurricane/DBos.h" +#include "hurricane/Name.h" +#include "hurricane/Properties.h" + + +namespace Hurricane { + + class JsonDBo; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::DBo". + + class DBo { + friend class JsonDBo; + public: + virtual void destroy (); + inline set& _getPropertySet (); + void _onDestroyed ( Property* property ); + Property* getProperty ( const Name& ) const; + Properties getProperties () const; + inline bool hasProperty () const; + void put ( Property* ); + void remove ( Property* ); + void removeProperty ( const Name& ); + void clearProperties (); + virtual void _toJson ( JsonWriter* ) const; + virtual void _toJsonProperties ( JsonWriter* ) const; + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + + private: + mutable set _propertySet; + + protected: + DBo (); + virtual ~DBo (); + virtual void _postCreate (); + virtual void _preDestroy (); + + private: + DBo ( const DBo& ); + DBo& operator= ( const DBo& ); + }; + + +// Inline Functions. + inline set& DBo::_getPropertySet () { return _propertySet; } + inline bool DBo::hasProperty () const { return !_propertySet.empty(); } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + + class JsonDBo : public JsonObject { + public: + JsonDBo ( unsigned long flags ); +}; + + +} // Hurricane namespace. + + +// inline void jsonWrite ( JsonWriter* w, const Hurricane::DBo* dbo ) +// { +// w->startObject(); +// std::string tname = dbo->_getTypeName(); +// if (w->issetFlags(JsonWriter::UsePlugReference) and (tname == "Plug")) { +// tname.insert( 0, "&" ); +// } +// jsonWrite( w, "@typename", tname ); +// dbo->_toJson( w ); +// dbo->_toJsonProperties( w ); +// w->endObject(); +// } + +INSPECTOR_P_SUPPORT(Hurricane::DBo); + +#endif // HURRICANE_DBO_H diff --git a/hurricane/src/hurricane/grenier/json/JsonReader.cpp b/hurricane/src/hurricane/grenier/json/JsonReader.cpp new file mode 100644 index 00000000..74c3b5c0 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/JsonReader.cpp @@ -0,0 +1,650 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./JsonReader.cpp" | +// +-----------------------------------------------------------------+ + + +#include "rapidjson/filereadstream.h" +#include "rapidjson/reader.h" +// Needed for registering. May be deleted later. +#include "hurricane/DebugSession.h" +#include "hurricane/Warning.h" +#include "hurricane/JsonReader.h" +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/Instance.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" + + +namespace { + + using namespace std; + using namespace rapidjson; + using namespace Hurricane; + + +// ------------------------------------------------------------------- +// Struct : "HurricaneHandler". + + class HurricaneHandler { + public: + HurricaneHandler ( JsonStack& ); + public: + bool Null (); + bool Bool ( bool ); + bool Int ( int ); + bool Int64 ( int64_t ); + bool Uint ( unsigned int ); + bool Uint64 ( uint64_t ); + bool Double ( double ); + bool String ( const char*, SizeType, bool copy ); + bool Key ( const char*, SizeType, bool copy ); + bool StartObject (); + bool EndObject ( SizeType ); + bool StartArray (); + bool EndArray ( SizeType ); + bool doCallToData () const; + private: + enum Flags { TypenameKey = (1<<0) + , ArrayMode = (1<<2) + , SkipObject = (1<<3) + , SkipArray = (1<<4) + , SkipMask = SkipObject | SkipArray + }; + private: + unsigned long _state; + string _key; + string _objectName; + vector _objects; + JsonStack& _stack; + }; + + + HurricaneHandler::HurricaneHandler ( JsonStack& stack ) + : _state (0) + , _key () + , _objectName() + , _objects () + , _stack (stack) + { } + + + bool HurricaneHandler::doCallToData () const + { return not _objects.empty() and _objects.back() and not _objects.back()->isCreated(); } + + + bool HurricaneHandler::Null () + { + //if (not _objects.empty()) ltrace(59) << "null _objects.back(): " << _objects.back() << endl; + + if (_state & SkipMask) return true; + _stack.push_back( _key, NULL ); + return true; + } + + + bool HurricaneHandler::Bool ( bool v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int ( int v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Int64 ( int64_t v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint ( unsigned int v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Uint64 ( uint64_t v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::Double ( double v ) + { + if (_state & SkipMask) return true; + _stack.push_back( _key, v ); + return true; + } + + + bool HurricaneHandler::String ( const char* value, SizeType, bool copy ) + { + if (_state & SkipMask) return true; + if (_state & TypenameKey) { + _state &= ~TypenameKey; + + JsonObject* object = JsonTypes::find( value ); + _objects[_objects.size()-1] = object->clone(); + + if (not object) { + cerr << Warning("JsonReader::parse(): Do not know how to parse type %s.", value ) << endl; + _state |= SkipObject; + } else { + _objects[_objects.size()-1]->setName( _objectName ); + } + + ltrace(51) << "HurricaneHandler::String() [key/typename] " << value << endl; + return true; + } + + _stack.push_back( _key, value ); + return true; + } + + + bool HurricaneHandler::Key ( const char* key, SizeType, bool copy ) + { + _key = key; + if (_state & SkipMask) { + _key.clear(); + return true; + } + + if (_state & TypenameKey) { + if (_key != "@typename") { + _state |= SkipObject; + _key.clear(); + } + return true; + } + + //ltrace(51) << "HurricaneHandler::Key() key:" << _key << " _objects.size():" << _objects.size() << endl; + + if (_objects.back()) { + if ( doCallToData() and not _key.empty() and (_key[0] != '_') ) { + // The key is no longer a simple attribute of the object. + // Triggers it's creation in the Json stack. + ltrace(51) << "HurricaneHandler::key() Calling " + << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( _stack ); + } + } + + return true; + } + + + bool HurricaneHandler::StartObject () + { + ltrace(50) << "Hurricane::StartObject()" << endl; + ltracein(50); + + _state |= TypenameKey; + // if (doCallToData()) { + // ltrace(51) << "Calling " << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + // _objects.back()->toData( _stack ); + // } + _objectName = (_key == ".Array") ? "" : _key; + _objects.push_back( NULL ); + ltrace(51) << "_objects.push_back(NULL), size():" << _objects.size() << "." << endl; + + ltracein(50); + return true; + } + + + bool HurricaneHandler::EndObject ( SizeType ) + { + ltraceout(50,2); + ltrace(50) << "HurricaneHandler::EndObject()" << endl; + ltracein(50); + + _objectName.clear(); + if (_state & SkipObject) { + _state &= ~SkipObject; + } else { + if (doCallToData()) { + ltrace(51) << "Calling " << _objects.back()->getTypeName() << "::toData(JsonStack&)." << endl; + _objects.back()->toData( _stack ); + } + if (_objects.size() > 1) { + ltrace(51) << "_objects.pop_back(), size():" << _objects.size() << "." << endl; + delete _objects.back(); + _objects.pop_back(); + } + if (_stack.size() > 1) { + if (_stack[-1].first[0] != '_') _stack.pop_back(); + } + } + ltraceout(50); + return true; + } + + + bool HurricaneHandler::StartArray() + { + ltrace(50) << "HurricaneHandler::StartArray() key:\"" << _key << "\"." << endl; + ltracein(50); + + _objectName.clear(); + if (_key.empty()) { _state |= SkipArray; return true; } + if (_key[0] != '+') { + cerr << Warning("JsonReader::parse(): Array attributes must start by \'+\' %s.", _key.c_str() ) << endl; + _state |= SkipArray; + return true; + } + + _state |= ArrayMode; + _key = ".Array"; + + return true; + } + + bool HurricaneHandler::EndArray ( SizeType ) + { + ltraceout(50); + ltrace(50) << "HurricaneHandler::EndArray()" << endl; + ltracein(50); + + _state &= ~(ArrayMode | SkipArray); + _key.clear(); + + ltraceout(50); + return true; + } + + +// ------------------------------------------------------------------- +// Class : "JsonReader". + + class JsonReader { + public: + enum Mode { CellMode = (1<<0) }; + public: + JsonReader (); + ~JsonReader (); + JsonReader* setFlags ( unsigned long mask ); + JsonReader* resetFlags ( unsigned long mask ); + bool issetFlags ( unsigned long mask ) const; + const JsonStack& getStack () const; + void parse ( std::string fileName, unsigned int flags ); + void close (); + private: + JsonReader ( const JsonReader& ); + JsonReader& operator= ( const JsonReader& ) const; + private: + unsigned long _flags; + size_t _bufferSize; + char* _buffer; + FILE* _file; + FileReadStream* _stream; + JsonStack _stack; + Reader _reader; + HurricaneHandler _handler; + }; + + + JsonReader::JsonReader () + : _flags (0) + , _bufferSize(65536) + , _buffer (new char [_bufferSize]) + , _file (NULL) + , _stream (NULL) + , _stack () + , _reader () + , _handler (_stack) + { + } + + + JsonReader::~JsonReader () + { + close(); + delete _buffer; + } + + + void JsonReader::close () + { + if (_stream) { delete _stream; _stream = NULL; } + if (_file ) { fclose(_file); _file = NULL; } + } + + + const JsonStack& JsonReader::getStack () const + { return _stack; } + + + void JsonReader::parse ( string fileName, unsigned int flags ) + { + close(); + + DebugSession::open( 50 ); + + fileName += ".json"; + _file = fopen( fileName.c_str(), "r" ); + cerr << "_file:" << _file << ", _buffer:" << (void*)_buffer << endl; + _stream = new FileReadStream ( _file, _buffer, _bufferSize ); + + _reader.Parse( *_stream, _handler ); + _stack.print( cerr ); + + DebugSession::close(); + close(); + } + + +} // local namespace. + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "JsonAttribute". + + JsonAttribute::~JsonAttribute () + { } + + +// ------------------------------------------------------------------- +// Class : "JsonStacked". + + JsonStacked::~JsonStacked () + { } + + + type_index JsonStacked::tid () const + { return typeid(JsonStacked); } + + + void JsonStacked::toJson ( JsonWriter*, boost::any object ) const + { + cerr << Error("JsonStacked::toJson() is a dummy method that should never be called.") << endl; + } + + + JsonStacked* JsonStacked::clone () const + { return new JsonStacked( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + JsonObject::JsonObject () + : _name () + , _stackeds () + , _attributes () + , _collections() + , _object () + { } + + + JsonObject::JsonObject ( const JsonObject& other ) + : _name (other._name) + , _stackeds () + , _attributes () + , _collections() + , _object () + { + for ( JsonAttribute* attribute : other._stackeds ) _stackeds.push_back( attribute->clone() ); + for ( JsonAttribute* attribute : other._attributes ) _stackeds.push_back( attribute->clone() ); + for ( JsonAttribute* attribute : other._collections ) _stackeds.push_back( attribute->clone() ); + } + + + JsonObject::~JsonObject () + { clear(); } + + + bool JsonObject::isJsonObject () const + { return _flags & IsJsonObject; } + + + void JsonObject::remove ( const std::string& key ) + { + if (key.empty()) { + cerr << Error( "JsonObject::remove(): Attempt to remove attribute with an empty name, ignored." ) << endl; + return; + } + + switch ( key[0] ) { + case '.': + for ( auto it = _stackeds.begin() ; it != _stackeds.end() ; ++it ) + if (key == (*it)->key()) { delete (*it); _stackeds.erase(it); break; } + break; + case '_': + for ( auto it = _attributes.begin() ; it != _attributes.end() ; ++it ) + if (key == (*it)->key()) { delete (*it); _attributes.erase(it); break; } + break; + case '+': + for ( auto it = _collections.begin() ; it != _collections.end() ; ++it ) + if (key == (*it)->key()) { delete (*it); _collections.erase(it); break; } + break; + } + } + + + bool JsonObject::has ( const std::string& key ) const + { + if (key.empty()) return false; + switch ( key[0] ) { + case '.': + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + if (key == _stackeds[i]->key()) return true; + break; + case '_': + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + if (key == _attributes[i]->key()) return true; + break; + case '+': + for ( size_t i=0 ; i<_collections.size() ; ++i ) + if (key == _collections[i]->key()) return true; + break; + } + return false; + } + + + bool JsonObject::check ( JsonStack& stack, string fname ) const + { + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) { + if (not stack.rhas(_stackeds[i]->key())) { + cerr << Error( "%s(): Stack is missing context element with key \"%s\"" + , fname.c_str(), _stackeds[i]->key().c_str() ) << endl; + return false; + } + } + for ( size_t i=0 ; i<_attributes.size() ; ++i ) { + if (not stack.rhas(_attributes[i]->key())) { + cerr << Error( "%s(): Stack is missing attribute element with key \"%s\"" + , fname.c_str(), _attributes[i]->key().c_str() ) << endl; + return false; + } + } + return true; + } + + + void JsonObject::toData ( JsonStack& ) + { } + + + void JsonObject::print ( ostream& o ) const + { + o << tab << "JsonObject for type: " << getTypeName() << endl; + for ( size_t i=0 ; i<_stackeds.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _stackeds[i]->key() + << " type:" << _stackeds[i]->tid().name() << endl; + + for ( size_t i=0 ; i<_attributes.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _attributes[i]->key() + << " type:" << _attributes[i]->tid().name() << endl; + + for ( size_t i=0 ; i<_collections.size() ; ++i ) + o << tab << "key:" << left << setw(20) << _collections[i]->key() + << " type:" << _collections[i]->tid().name() << endl; + } + + + JsonKey::JsonKey ( const string& key ) + : JsonObject() + , _key (key) + { } + + + string JsonKey::getTypeName () const + { return _key; } + + + JsonKey* JsonKey::clone () const + { return new JsonKey ( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + JsonTypes* JsonTypes::_jsonTypes = NULL; + + + JsonTypes::JsonTypes () + : _jsonObjects() + { } + + + JsonTypes::~JsonTypes () + { + for ( JsonObject* object : _jsonObjects ) delete object; + } + + + void JsonTypes::_registerType ( JsonObject* object ) + { + if (_find(object->getTypeName())) { + throw Error( "JsonTypes::_registerType(): Attempt to register <%s> twice.", object->getTypeName().c_str() ); + } + _jsonObjects.insert( object ); + } + + + JsonObject* JsonTypes::_find ( const string& tname ) + { + JsonKey key( tname ); + set::iterator it = _jsonObjects.find( &key ); + if (it != _jsonObjects.end()) return (*it); + return NULL; + } + + + void JsonTypes::registerType ( JsonObject* object ) + { + if (not _jsonTypes) initialize(); + _jsonTypes->_registerType( object ); + } + + + JsonObject* JsonTypes::find ( const string& tname ) + { + if (not _jsonTypes) initialize(); + return _jsonTypes->_find( tname ); + } + + + void JsonTypes::initialize () + { + if (_jsonTypes) return; + + _jsonTypes = new JsonTypes (); + _jsonTypes->_registerType( new JsonPoint (0) ); + _jsonTypes->_registerType( new JsonBox (0) ); + _jsonTypes->_registerType( new JsonTransformation(0) ); + _jsonTypes->_registerType( new JsonCell (0) ); + _jsonTypes->_registerType( new JsonNet (0) ); + _jsonTypes->_registerType( new JsonPlugRef (0) ); + _jsonTypes->_registerType( new JsonRoutingPad (0) ); + _jsonTypes->_registerType( new JsonContact (0) ); + _jsonTypes->_registerType( new JsonVertical (0) ); + _jsonTypes->_registerType( new JsonHorizontal (0) ); + _jsonTypes->_registerType( new JsonPad (0) ); + _jsonTypes->_registerType( new JsonInstance (0) ); + _jsonTypes->_registerType( new JsonPlug (0) ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + void JsonStack::addEntity ( unsigned int jsonId, Entity* entity ) + { _entities.insert( std::make_pair(jsonId,entity) ); } + + + void JsonStack::print ( ostream& o ) const + { + o << tab << "JsonStack::print() Stack contains " << _stack.size() << " elements." << endl; + for ( size_t i=0 ; i<_stack.size() ; ++i ) { + o << "[" << right << setw(2) << i << "] key: \"" << left << setw(20) << _stack[i].first + << "\", type: \"" << demangle(_stack[i].second.type()) << "\"." << endl; + } + } + + +// ------------------------------------------------------------------- +// Function : Json Cell parser. + + Cell* jsonCellParse ( string filename ) + { + JsonReader reader; + reader.parse( filename, JsonReader::CellMode ); + + const JsonStack& stack = reader.getStack(); + if (stack.rhas(".Cell")) return stack.as(".Cell"); + return NULL; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/grenier/json/JsonReader.h b/hurricane/src/hurricane/grenier/json/JsonReader.h new file mode 100644 index 00000000..79e2d5f0 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/JsonReader.h @@ -0,0 +1,790 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/JsonReader.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_JSON_READER_H +#define HURRICANE_JSON_READER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Hurricane { + + class Entity; + class Cell; + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonStack; + class JsonArray { }; + + +// ------------------------------------------------------------------- +// Class : "JsonAttribute". + + class JsonAttribute { + public: + inline JsonAttribute ( const std::string& key, unsigned long flags ); + virtual ~JsonAttribute (); + inline std::string key () const; + virtual std::type_index tid () const = 0; + virtual void toJson ( JsonWriter*, boost::any object ) const = 0; + virtual JsonAttribute* clone () const = 0; + inline void setFlags ( unsigned long mask ); + inline void resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + private: + std::string _key; + unsigned long _flags; + }; + + inline JsonAttribute::JsonAttribute ( const std::string& key, unsigned long flags ): _key(key), _flags(flags) { } + inline std::string JsonAttribute::key () const { return _key; } + inline void JsonAttribute::setFlags ( unsigned long mask ) { _flags |= mask; } + inline void JsonAttribute::resetFlags ( unsigned long mask ) { _flags &= ~mask; } + inline bool JsonAttribute::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + +// ------------------------------------------------------------------- +// Class : "JsonStacked". + + class JsonStacked : public JsonAttribute { + public: + inline JsonStacked ( const std::string& key ); + virtual ~JsonStacked (); + virtual std::type_index tid () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + virtual JsonStacked* clone () const; + }; + + inline JsonStacked::JsonStacked ( const std::string& key ): JsonAttribute(key,0) { } + + +// ------------------------------------------------------------------- +// Class : "JsonAnyAttribute". + + template + class JsonAnyAttribute : public JsonAttribute { + public: + JsonAnyAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ); + virtual ~JsonAnyAttribute (); + virtual std::type_index tid () const; + virtual JsonAnyAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T C::* _attribute; + }; + + + template + JsonAnyAttribute::JsonAnyAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + { } + + template + JsonAnyAttribute::~JsonAnyAttribute () + { } + + template + std::type_index JsonAnyAttribute::tid () + { return typeid(T); } + + template + JsonAnyAttribute* JsonAnyAttribute::clone () const + { return new JsonAnyAttribute( *this ); } + + +// ------------------------------------------------------------------- +// Class : "JsonStrAttribute". + + template + class JsonStrAttribute : public JsonAttribute { + public: + JsonStrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ); + virtual ~JsonStrAttribute (); + virtual std::type_index tid () const; + virtual JsonStrAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T C::* _attribute; + }; + + + template + JsonStrAttribute::JsonStrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + { } + + template + JsonStrAttribute::~JsonStrAttribute () + { } + + template + std::type_index JsonStrAttribute::tid () + { return typeid(T); } + + template + JsonStrAttribute* JsonStrAttribute::clone () const + { return new JsonStrAttribute( *this ); } + + template + void JsonStrAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), getString( boost::any_cast(object)->*_attribute ) ); } + + +// ------------------------------------------------------------------- +// Class : "JsonFtrrAttribute". + + template + class JsonFtrrAttribute : public JsonAttribute { + public: + JsonFtrrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + , std::function tr + ); + virtual ~JsonFtrrAttribute (); + virtual std::type_index tid () const; + virtual JsonFtrrAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T C::* _attribute; + std::function _tr; + }; + + + template + JsonFtrrAttribute::JsonFtrrAttribute ( const std::string& key + , unsigned long flags + , T C::* attr + , std::function tr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + , _tr (tr) + { } + + template + JsonFtrrAttribute::~JsonFtrrAttribute () + { } + + template + std::type_index JsonFtrrAttribute::tid () + { return typeid(T); } + + template + JsonFtrrAttribute* JsonFtrrAttribute::clone () const + { return new JsonFtrrAttribute( *this ); } + + template + void JsonFtrrAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), _tr( boost::any_cast(object)->*_attribute ) ); } + + +// ------------------------------------------------------------------- +// Class : "JsonFtrpAttribute". + + template + class JsonFtrpAttribute : public JsonAttribute { + public: + JsonFtrpAttribute ( const std::string& key + , unsigned long flags + , T* C::* attr + , std::function tr + ); + virtual ~JsonFtrpAttribute (); + virtual std::type_index tid () const; + virtual JsonFtrpAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + T* C::* _attribute; + std::function _tr; + }; + + + template + JsonFtrpAttribute::JsonFtrpAttribute ( const std::string& key + , unsigned long flags + , T* C::* attr + , std::function tr + ) + : JsonAttribute(key,flags) + , _attribute (attr) + , _tr (tr) + { } + + template + JsonFtrpAttribute::~JsonFtrpAttribute () + { } + + template + std::type_index JsonFtrpAttribute::tid () + { return typeid(T); } + + template + JsonFtrpAttribute* JsonFtrpAttribute::clone () const + { return new JsonFtrpAttribute( *this ); } + + template + void JsonFtrpAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), _tr( boost::any_cast(object)->*_attribute ) ); } + + +// ------------------------------------------------------------------- +// Class : "JsonMethAttribute". + + template + class JsonMethAttribute : public JsonAttribute { + public: + JsonMethAttribute ( const std::string& key + , unsigned long flags + , R (C::* meth )() const + ); + virtual ~JsonMethAttribute (); + virtual std::type_index tid () const; + virtual JsonMethAttribute* clone () const; + virtual void toJson ( JsonWriter*, boost::any object ) const; + private: + R (C::* _meth)() const; + }; + + + template + JsonMethAttribute::JsonMethAttribute ( const std::string& key + , unsigned long flags + , R (C::* meth)() const + ) + : JsonAttribute(key,flags) + , _meth (meth) + { } + + template + JsonMethAttribute::~JsonMethAttribute () + { } + + template + std::type_index JsonMethAttribute::tid () + { return typeid(R); } + + template + JsonMethAttribute* JsonMethAttribute::clone () const + { return new JsonMethAttribute( *this ); } + + template + void JsonMethAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), (boost::any_cast(object)->*_meth)() ); } + + +// ------------------------------------------------------------------- +// Class : "JsonAnyAttribute". + +#define JSON_POD_ATTRIBUTE(pod_t) \ + template \ + class JsonAnyAttribute : public JsonAttribute { \ + public: \ + JsonAnyAttribute ( const std::string& key \ + , unsigned long flags \ + , pod_t C::* attr \ + ); \ + virtual ~JsonAnyAttribute (); \ + virtual std::type_index tid () const; \ + virtual JsonAnyAttribute* clone () const; \ + virtual void toJson ( JsonWriter*, boost::any object ) const; \ + private: \ + pod_t C::* _attribute; \ + }; \ + \ + \ + template \ + JsonAnyAttribute::JsonAnyAttribute ( const std::string& key \ + , unsigned long flags \ + , pod_t C::* attr \ + ) \ + : JsonAttribute(key,flags) \ + , _attribute (attr) \ + { } \ + \ + template \ + JsonAnyAttribute::~JsonAnyAttribute () \ + { } \ + \ + template \ + std::type_index JsonMethAttribute::tid () \ + { return typeid(pod_t); } \ + \ + template \ + JsonAnyAttribute* JsonAnyAttribute::clone () const \ + { return new JsonAnyAttribute( *this ); } \ + \ + template \ + void JsonAnyAttribute::toJson ( JsonWriter* w, boost::any object ) const \ + { jsonWrite( w, key(), boost::any_cast(object)->*_attribute ); } + + +// Build a specialized JsonAnyAttribute for all POD types. + JSON_POD_ATTRIBUTE(bool) + JSON_POD_ATTRIBUTE(int) + JSON_POD_ATTRIBUTE(long) + JSON_POD_ATTRIBUTE(unsigned int) + JSON_POD_ATTRIBUTE(unsigned long) + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonObject { + public: + enum Flags { IsJsonObject = (1<<0) + , UsePlugReference = (1<<1) + , UseReference = (1<<3) + }; + public: + JsonObject (); + JsonObject ( const JsonObject& ); + virtual ~JsonObject (); + virtual std::string getTypeName () const = 0; + inline std::string getStackName () const; + virtual bool isJsonObject () const; + bool check ( JsonStack&, string fname ) const; + void print ( std::ostream& ) const; + bool has ( const std::string& key ) const; + template + inline T get ( JsonStack&, const std::string& key ) const; + void add ( const std::string& key, unsigned long flags ); + template + void add ( const std::string& key, T C::* attr, unsigned long flags ); + template + void add ( const std::string& key, T C::* attr, R(*tr)(T&), unsigned long flags ); + template + void add ( const std::string& key, T* C::* attr, R(*tr)(T*), unsigned long flags ); + template + void add ( const std::string& key, R(C::* meth)() const, unsigned long flags ); + template + void addS ( const std::string& key, T C::* attr, unsigned long flags ); + void remove ( const std::string& key ); + template + T access ( const std::string& key ); + inline void clear (); + inline std::string getName () const; + inline void setName ( const string& ); + template inline T& getObject () const; + template inline void setObject ( T& ) ; + inline bool isCreated () const; + virtual JsonObject* clone () const = 0; + template void toJson ( JsonWriter*, C* object ) const; + virtual void toData ( JsonStack& ); + template inline void update ( JsonStack&, T ); + inline void setFlags ( unsigned long mask ); + inline void resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + protected: + inline bool _checkKey ( const std::string& key ) const; + protected: + unsigned long _flags; + std::string _name; + std::vector _stackeds; + std::vector _attributes; + std::vector _collections; + boost::any _object; + }; + + + inline bool JsonObject::isCreated () const { return not _object.empty(); } + inline std::string JsonObject::getName () const { return _name; } + inline void JsonObject::setName ( const string& name ) { _name=name; } + inline void JsonObject::setFlags ( unsigned long mask ) { _flags |= mask; } + inline void JsonObject::resetFlags ( unsigned long mask ) { _flags &= ~mask; } + inline bool JsonObject::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + inline std::string JsonObject::getStackName () const + { return (_name.empty()) ? std::string(".")+getTypeName(): _name; } + + template inline T& JsonObject::getObject () const + { return boost::any_cast(_object); } + + template inline void JsonObject::setObject ( T& t ) + { _object = t; } + + + bool JsonObject::checkKey ( const std::string& key ) const + { + if (key.empty()) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute with an empty name, ignored." + << endl; + return false; + } + if (has(key)) { + cerr << "[ERROR] JsonObject::add(): Attempt to add attribute \"" << key << "\" twice, cancelled." + << endl; + return false; + } + return true; + } + + + void JsonObject::add ( const std::string& key ) + { + if ( _checkKey(key) and (key[0] == '.') ) { + _stackeds.push_back( new JsonStacked(key) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Stack requirement key \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, T C::* attr, unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonAnyAttribute(key,flags,attr) ); + case '+': _attributes.push_back( new JsonAnyAttribute(key,flags,attr) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, T C::* attr, R(*tr)(T&), unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonFtrrAttribute(key,flags,attr,std::function(tr)) ); + case '+': _attributes.push_back( new JsonFtrrAttribute(key,flags,attr,std::function(tr)) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, T* C::* attr, R(*tr)(T*), unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonFtrpAttribute(key,flags,attr,std::function(tr)) ); + case '+': _attributes.push_back( new JsonFtrpAttribute(key,flags,attr,std::function(tr)) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::add( const std::string& key, R(C::*meth)() const, unsigned long flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonMethAttribute(key,flags,meth) ); + case '+': _attributes.push_back( new JsonMethAttribute(key,flags,meth) ); + return; + } + cerr << "[ERROR] JsonObject::add(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template + void JsonObject::addS( const std::string& key, T C::* attr, unsigned int flags ) + { + if (not _checkKey(key)) return; + switch ( key[0] ) { + case '_': _attributes.push_back( new JsonStrAttribute(key,flags,attr) ); + return; + } + cerr << "[ERROR] JsonObject::addS(): Key name \"" << key + << "\" do not follow naming convention, cancelled." << endl; + } + + + template void JsonObject::toJson ( JsonWriter* w, C* object ) const + { + if (isJsonObject()) { + w->startObject(); + jsonWrite( w, "@typename", getTypeName() ); + for ( JsonAttribute* attribute : _attributes ) attribute ->toJson( w, object ); + for ( JsonAttribute* collection : _collections ) collection->toJson( w, object ); + w->endObject(); + } + } + + + inline void JsonObject::clear () + { + for ( JsonAttribute* attribute : _stackeds ) delete attribute; + for ( JsonAttribute* attribute : _attributes ) delete attribute; + for ( JsonAttribute* attribute : _collections ) delete attribute; + + _stackeds .clear(); + _attributes .clear(); + _collections.clear(); + } + + + class JsonKey : public JsonObject { + public: + inline JsonKey ( const std::string& ); + virtual std::string getTypeName () const; + virtual JsonKey* clone () const; + private: + std::string _key; + }; + + +} // Hurricane namespace. + + +namespace std { + + template<> + struct less { + inline bool operator() ( const Hurricane::JsonObject* lhs, const Hurricane::JsonObject* rhs ) + { return lhs->getTypeName() < rhs->getTypeName(); } + }; + +} // std namespace. + + +namespace Hurricane { + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + class JsonTypes { + public: + static void initialize (); + static void registerType ( JsonObject* ); + static JsonObject* find ( const std::string& tname ); + private: + JsonTypes (); + ~JsonTypes (); + JsonTypes ( const JsonTypes& ); + void _registerType ( JsonObject* ); + JsonObject* _find ( const std::string& tname ); + private: + static JsonTypes* _jsonTypes; + std::set _jsonObjects; + }; + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + class JsonStack { + public: + typedef std::pair Element; + public: + inline JsonStack (); + inline size_t size () const; + template inline void push_back ( const std::string&, T ); + inline void pop_back ( size_t count=1 ); + inline int rhas ( const std::string& ) const; + template inline T as ( const std::string& ) const; + template inline T as ( int ) const; + template inline T getEntity ( unsigned int ) const; + void addEntity ( unsigned int jsonId, Entity* ); + void print ( std::ostream& ) const; + inline JsonStack* setFlags ( unsigned long mask ); + inline JsonStack* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + inline const Element& operator[] ( int index ) const; + private: + unsigned long _flags; + vector _stack; + std::map _entities; + }; + + + inline JsonStack::JsonStack () + : _flags(0), _stack(), _entities() + { } + + template inline void JsonStack::push_back ( const std::string& key, T t ) { + ltrace(51) << "JsonStack::push_back() key:" << key << " t:" << t + << " (" << demangle(typeid(T)) << ")." << endl; + _stack.push_back(std::make_pair(key,boost::any(t))); + } + + inline void JsonStack::pop_back ( size_t count ) + { while (count--) { + if (_stack.empty()) { + std::cerr << "[ERROR] JsonStack::pop_back(): Stack is empty, but " + << (count+1) << " elements remains to pop." << std::endl; + break; + } + ltrace(51) << "| _stack.pop_back() " << _stack.back().first << endl; + _stack.pop_back(); + } + } + + inline const JsonStack::Element& JsonStack::operator[] ( int index ) const + { + if (index < 0) return _stack[_stack.size()+index]; + return _stack[index]; + } + + inline int JsonStack::rhas ( const std::string& key ) const + { + if (_stack.empty()) return 0; + + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" found at index:" + << (i-(int)_stack.size()) << " (i:" << i << ")." << endl; + return i-(int)_stack.size(); + } + if (i == 0) break; + --i; + } while ( true ); + + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" not found (returning index: 0)." << endl; + return 0; + } + + template inline T JsonStack::as ( const std::string& key ) const + { + if (not _stack.empty()) { + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::as() k:" << key + << " t:" << _stack[i].second.type().name() << std::endl; + return boost::any_cast( _stack[i].second ); + } + if (i == 0) break; + --i; + } while ( true ); + + std::cerr << "[ERROR] JsonStack::as(key): No element with key \"" + << key << "\" in stack." << std::endl; + } else { + std::cerr << "[ERROR] JsonStack::as(key): Stack is empty while searching for key \"" + << key << "\"." << std::endl; + } + + return T(); + } + + template inline T JsonStack::as ( int index ) const + { + size_t i = (index >= 0) ? index : (_stack.size()+index); + return boost::any_cast( _stack[i].second ); + } + + template inline T JsonStack::getEntity ( unsigned int id ) const { + std::map::const_iterator it = _entities.find(id); + if (it == _entities.end()) return NULL; + return dynamic_cast((*it).second); + } + + inline size_t JsonStack::size () const { return _stack.size(); } + inline JsonStack* JsonStack::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonStack* JsonStack::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonStack::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + + template + T JsonObject::get ( JsonStack& stack, const std::string& key ) const + { + int index = stack.rhas(key); + if (index == 0) return T();; + + return stack.as( index ); + } + + template inline void JsonObject::update ( JsonStack& stack, T hobject ) + { + stack.pop_back( _attributes.size() ); + stack.push_back( getStackName(), hobject ); + setObject( hobject ); + } + + +// ------------------------------------------------------------------- +// Function : Json Cell parser. + + Cell* jsonCellParse ( std::string filename ); + + +} // Hurricane namespace. + + +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, const C* object, unsigned long flags ) +{ + w->key( key ); + Hurricane::JsonObject* jobject = C::getJsonObject(flags); + jobject->toJson( w, object ); + delete jobject; +} + + +namespace Hurricane { + +// Delayed "void JsonAnyAttribute::toJson()" template definition, because +// it needs the jsonWrite<> template specialisation for "const T*", which can +// be only declared after "JsonObject". + + template + void JsonAnyAttribute::toJson ( JsonWriter* w, boost::any object ) const + { jsonWrite( w, key(), &(boost::any_cast(object)->*_attribute) ); } + +} // Hurricane namespace. + +#endif // HURRICANE_JSON_READER_H diff --git a/hurricane/src/hurricane/grenier/json/Net.cpp b/hurricane/src/hurricane/grenier/json/Net.cpp new file mode 100644 index 00000000..e2e9c1e9 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/Net.cpp @@ -0,0 +1,1106 @@ +// **************************************************************************************************** +// File: ./Net.cpp +// Authors: R. Escassut +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU +// Lesser General Public License as published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane 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 Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If +// not, see . +// **************************************************************************************************** + +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Plug.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/RoutingPads.h" +#include "hurricane/Pin.h" +#include "hurricane/Contact.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Pad.h" +#include "hurricane/UpdateSession.h" +#include "hurricane/Error.h" + +namespace Hurricane { + + + +// **************************************************************************************************** +// Filters declaration & implementation +// **************************************************************************************************** + +class Net_IsCellNetFilter : public Filter { +// ******************************************* + + public: Net_IsCellNetFilter() {}; + + public: Net_IsCellNetFilter(const Net_IsCellNetFilter& filter) {}; + + public: Net_IsCellNetFilter& operator=(const Net_IsCellNetFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsCellNetFilter(*this);}; + + public: virtual bool accept(Net* net) const {return !net->isDeepNet();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsCellNetFilter>");}; + +}; + +class Net_IsDeepNetFilter : public Filter { +// ******************************************* + + public: Net_IsDeepNetFilter() {}; + + public: Net_IsDeepNetFilter(const Net_IsDeepNetFilter& filter) {}; + + public: Net_IsDeepNetFilter& operator=(const Net_IsDeepNetFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsDeepNetFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isDeepNet();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsDeepNetFilter>");}; + +}; + +class Net_IsGlobalFilter : public Filter { +// ******************************************* + + public: Net_IsGlobalFilter() {}; + + public: Net_IsGlobalFilter(const Net_IsGlobalFilter& filter) {}; + + public: Net_IsGlobalFilter& operator=(const Net_IsGlobalFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsGlobalFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isGlobal();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsGlobalFilter>");}; + +}; + +class Net_IsExternalFilter : public Filter { +// ********************************************* + + public: Net_IsExternalFilter() {}; + + public: Net_IsExternalFilter(const Net_IsExternalFilter& filter) {}; + + public: Net_IsExternalFilter& operator=(const Net_IsExternalFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsExternalFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isExternal();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsExternalFilter>");}; + +}; + +class Net_IsClockFilter : public Filter { +// ****************************************** + + public: Net_IsClockFilter() {}; + + public: Net_IsClockFilter(const Net_IsClockFilter& filter) {}; + + public: Net_IsClockFilter& operator=(const Net_IsClockFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsClockFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isClock();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsClockFilter>");}; + +}; + +class Net_IsSupplyFilter : public Filter { +// ******************************************* + + public: Net_IsSupplyFilter() {}; + + public: Net_IsSupplyFilter(const Net_IsSupplyFilter& filter) {}; + + public: Net_IsSupplyFilter& operator=(const Net_IsSupplyFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsSupplyFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isSupply();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsSupplyFilter>");}; + +}; + +class Net_IsPowerFilter : public Filter { +// ******************************************* + + public: Net_IsPowerFilter() {}; + + public: Net_IsPowerFilter(const Net_IsPowerFilter& filter) {}; + + public: Net_IsPowerFilter& operator=(const Net_IsPowerFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsPowerFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isPower();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsPowerFilter>");}; + +}; + +class Net_IsGroundFilter : public Filter { +// ******************************************* + + public: Net_IsGroundFilter() {}; + + public: Net_IsGroundFilter(const Net_IsGroundFilter& filter) {}; + + public: Net_IsGroundFilter& operator=(const Net_IsGroundFilter& filter) {return *this;}; + + public: virtual Filter* getClone() const {return new Net_IsGroundFilter(*this);}; + + public: virtual bool accept(Net* net) const {return net->isGround();}; + + public: virtual string _getString() const {return "<" + _TName("Net::IsGroundFilter>");}; + +}; + + + +// **************************************************************************************************** +// Net_SlavePlugs implementation +// **************************************************************************************************** + +class Net_SlavePlugs : public Collection { +// ******************************************** + +// Types +// ***** + + public: typedef Collection Inherit; + + public: class Locator : public Hurricane::Locator { + // ***************************************************** + + public: typedef Hurricane::Locator Inherit; + + private: const Net* _net; + private: Plug* _plug; + private: InstanceLocator _instanceLocator; + + public: Locator(const Net* net = NULL); + public: Locator(const Locator& locator); + + public: Locator& operator=(const Locator& locator); + + public: virtual Plug* getElement() const; + public: virtual Hurricane::Locator* getClone() const; + + public: virtual bool isValid() const; + + public: virtual void progress(); + + public: virtual string _getString() const; + + }; + +// Attributes +// ********** + + private: const Net* _net; + +// Constructors +// ************ + + public: Net_SlavePlugs(const Net* net = NULL); + public: Net_SlavePlugs(const Net_SlavePlugs& slavePlugs); + +// Operators +// ********* + + public: Net_SlavePlugs& operator=(const Net_SlavePlugs& slavePlugs); + +// Accessors +// ********* + + public: virtual Collection* getClone() const; + public: virtual Hurricane::Locator* getLocator() const; + +// Others +// ****** + + public: virtual string _getString() const; + +}; + + + +// **************************************************************************************************** +// Net implementation +// **************************************************************************************************** + +Net::Net(Cell* cell, const Name& name) +// *********************************** +: Inherit(), + _cell(cell), + _name(name), + _arity(1), + _isGlobal(false), + _isExternal(false), + _isAutomatic(false), + _type(Type::LOGICAL), // default is Type::LOGICAL : no more Type::Undefined - Damien.Dupuis 01/10/2010 + _direction(), + _position(0,0), + _componentSet(), + _rubberSet(), + _nextOfCellNetMap(NULL), + _mainName(this) +{ + if (!_cell) + throw Error("Can't create " + _TName("Net") + " : null cell"); + + if (name.isEmpty()) + throw Error("Can't create " + _TName("Net") + " : empty name"); + + if (_cell->getNet(_name)) + throw Error("Can't create " + _TName("Net ") + getString(_name) + " : already exists"); +} + +Net* Net::create(Cell* cell, const Name& name) +// ******************************************* +{ + Net* net = new Net(cell, name); + + net->_postCreate(); + + return net; +} + +Box Net::getBoundingBox() const +// **************************** +{ + Box boundingBox; + for_each_component(component, getComponents()) { + boundingBox.merge(component->getBoundingBox()); + end_for; + } + return boundingBox; +} + +RoutingPads Net::getRoutingPads() const +// ************************ +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Plugs Net::getPlugs() const +// ************************ +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Pins Net::getPins() const +// ********************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Contacts Net::getContacts() const +// ****************************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Segments Net::getSegments() const +// ****************************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Verticals Net::getVerticals() const +// ******************************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Horizontals Net::getHorizontals() const +// ************************************ +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Pads Net::getPads() const +// ********************** +{ + // return getComponents().getSubSet(); + return SubTypeCollection(getComponents()); +} + +Plugs Net::getSlavePlugs() const +// ***************************** +{ + return Net_SlavePlugs(this); +} + +Plugs Net::getConnectedSlavePlugs() const +// ************************************** +{ + return getSlavePlugs().getSubSet(Plug::getIsConnectedFilter()); +} + +Plugs Net::getUnconnectedSlavePlugs() const +// **************************************** +{ + return getSlavePlugs().getSubSet(Plug::getIsUnconnectedFilter()); +} + +NetFilter Net::getIsCellNetFilter() +// ******************************* +{ + return Net_IsCellNetFilter(); +} + +NetFilter Net::getIsDeepNetFilter() +// ******************************* +{ + return Net_IsDeepNetFilter(); +} + +NetFilter Net::getIsGlobalFilter() +// ******************************* +{ + return Net_IsGlobalFilter(); +} + +NetFilter Net::getIsExternalFilter() +// ********************************* +{ + return Net_IsExternalFilter(); +} + +NetFilter Net::getIsInternalFilter() +// ********************************* +{ + return !Net_IsExternalFilter(); +} + +NetFilter Net::getIsClockFilter() +// ****************************** +{ + return Net_IsClockFilter(); +} + +NetFilter Net::getIsSupplyFilter() +// ******************************* +{ + return Net_IsSupplyFilter(); +} + +NetFilter Net::getIsPowerFilter() +// ******************************* +{ + return Net_IsPowerFilter(); +} + +NetFilter Net::getIsGroundFilter() +// ******************************* +{ + return Net_IsGroundFilter(); +} + +void Net::setName(const Name& name) +// ******************************** +{ + if (name != _name) { + if (name.isEmpty()) + throw Error("Can't change net name : empty name"); + + if (_cell->getNet(name)) + throw Error("Can't change net name : already exists"); + + _cell->_getNetMap()._remove(this); + _name = name; + _cell->_getNetMap()._insert(this); + } +} + +void Net::setArity(const Arity& arity) +// *********************************** +{ + _arity = arity; +} + +void Net::setGlobal(bool isGlobal) +// ******************************* +{ + _isGlobal = isGlobal; +} + +void Net::setExternal(bool isExternal) +// *********************************** +{ + if (isExternal != _isExternal) { + if (!isExternal) { + if (!getConnectedSlavePlugs().isEmpty()) + throw Error("Can't set internal : has connected slave plugs"); + _direction = Direction::UNDEFINED; + } + _isExternal = isExternal; + if (_isExternal) { + UpdateSession::open(); + setPosition(Point(0,0)); + for_each_instance(instance, _cell->getSlaveInstances()) { + Plug::_create(instance, this); + end_for; + } + UpdateSession::close(); + } + } +} + +void Net::setAutomatic(bool isAutomatic) +// ************************************* +{ + _isAutomatic = isAutomatic; +} + +void Net::setType(const Type& type) +// ******************************** +{ + _type = type; +} + +void Net::setPosition(const Point& position) +// ***************************************** +{ + if (_position != position) { + for_each_plug(plug, getSlavePlugs()) { + plug->invalidate(true); + end_for; + } + _position = position; + } +} + +void Net::setDirection(const Direction& direction) +// *********************************************** +{ + _direction = direction; +} + +bool Net::addAlias(const Name& name ) +// ********************************** +{ + if (getCell()->getNet(name)) { + cerr << Warning( "Net::addAlias(): Cannot add alias %s to net %s, already taken." + , getString(name).c_str() + , getString(getName()).c_str() + ) << endl; + return false; + } + + NetAliasName* slave = new NetAliasName ( name ); + _mainName.attach( slave ); + getCell()->_addNetAlias( slave ); + + return true; +} + +bool Net::removeAlias(const Name& name ) +// ************************************* +{ + NetAliasName* slave = _mainName.find( name ); + if (slave) { + slave->detach(); + getCell()->_removeNetAlias( slave ); + return true; + } + return false; +} + +Net* Net::getClone(Cell* clonedCell) +// ********************************* +{ + Net* clonedNet = Net::create( clonedCell, getName() ); + clonedNet->setArity ( getArity() ); + clonedNet->setGlobal ( isGlobal() ); + clonedNet->setExternal ( isExternal() ); + clonedNet->setType ( getType() ); + clonedNet->setDirection( getDirection() ); + + return clonedNet; +} + +void Net::materialize() +// ******************** +{ + for_each_component(component, getComponents()) { + component->materialize(); + end_for; + } + for_each_rubber(rubber, getRubbers()) { + rubber->materialize(); + end_for; + } +} + +void Net::unmaterialize() +// ********************** +{ + for_each_rubber(rubber, getRubbers()) { + rubber->unmaterialize(); + end_for; + } + for_each_component(component, getComponents()) { + component->unmaterialize(); + end_for; + } +} + +static void mergeNets(Net* net1, Net* net2) +// **************************************** +{ + assert(net1); + assert(net2); + + if (net2->getName()[0] != '~') { + if ((net1->getName()[0] == '~') || + (net2->isGlobal() && !net1->isGlobal()) || + (net2->isExternal() && !net1->isExternal())) { + Net* tmpNet = net1; + net1 = net2; + net2 = tmpNet; + } + } + + if (net2->isExternal() && !net1->isExternal()) { + Net* tmpNet = net1; + net1 = net2; + net2 = tmpNet; + } + + net1->merge(net2); +} + +void Net::merge(Net* net) +// ********************** +{ + if (!net) + throw Error("Can't merge net : null net"); + + if (net == this) + throw Error("Can't merge net : itself"); + + if (net->getCell() != _cell) + throw Error("Can't merge net : incompatible net"); + + if (!isExternal() && net->isExternal() && !net->getConnectedSlavePlugs().isEmpty()) + throw Error("Can't merge net : incompatible net"); + + for_each_rubber(rubber, net->getRubbers()) rubber->_setNet(this); end_for; + for_each_component(component, net->getComponents()) component->_setNet(this); end_for; + + if (isExternal() && net->isExternal()) { + for_each_plug(plug, net->getConnectedSlavePlugs()) { + Plug* mainPlug = plug->getInstance()->getPlug(this); + if (mainPlug->isConnected() && (mainPlug->getNet() != plug->getNet())) + mergeNets(mainPlug->getNet(), plug->getNet()); + end_for; + } + for_each_plug(plug, net->getConnectedSlavePlugs()) { + Plug* mainPlug = plug->getInstance()->getPlug(this); + if (!mainPlug->isConnected()) mainPlug->setNet(plug->getNet()); + Hook* masterHook = plug->getBodyHook(); + Hook* nextMasterHook = masterHook->getNextMasterHook(); + if (nextMasterHook != masterHook) { + masterHook->detach(); + mainPlug->getBodyHook()->merge(nextMasterHook); + } + Hooks slaveHooks = masterHook->getSlaveHooks(); + while (!slaveHooks.isEmpty()) { + Hook* slaveHook = slaveHooks.getFirst(); + slaveHook->detach(); + slaveHook->attach(mainPlug->getBodyHook()); + } + plug->_destroy(); + end_for; + } + } + + Name mergedName = net->getName(); + NetAliasName* slaves = NULL; + if (net->_mainName.isAttached()) { + slaves = dynamic_cast( net->_mainName.getNext() ); + net->_mainName.detach(); + } + + if (net->isExternal() and not isExternal()) + setExternal( true ); + net->destroy(); + + if (slaves) _mainName.attach( slaves ); + addAlias( mergedName ); +} + +void Net::_postCreate() +// ******************** +{ + _cell->_getNetMap()._insert(this); + + if (_isExternal) { + for_each_instance(instance, _cell->getSlaveInstances()) { + Plug::_create(instance, this); + end_for; + } + } + + Inherit::_postCreate(); +} + +void Net::_preDestroy() +// ******************* +{ + Inherit::_preDestroy(); + + for_each_plug(slavePlug, getSlavePlugs()) slavePlug->_destroy(); end_for; + + unmaterialize(); + + for_each_rubber(rubber, getRubbers()) rubber->_destroy(); end_for; + + for_each_component(component, getComponents()) { + for_each_hook(hook, component->getHooks()) { + // 15 05 2006 xtof : detach all hooks in rings when + // a net deletion occurs, can't see why master hooks were not detached. + //if (!hook->IsMaster()) hook->detach(); + hook->detach(); + end_for; + } + end_for; + } + + for_each_component(component, getComponents()) { + if (!dynamic_cast(component)) + component->destroy(); + else + ((Plug*)component)->setNet(NULL); + end_for; + } + + _mainName.clear(); + _cell->_getNetMap()._remove(this); +} + +string Net::_getString() const +// *************************** +{ + string s = Inherit::_getString(); + s.insert(s.length() - 1, " " + getString(_name)); + return s; +} + +Record* Net::_getRecord() const +// ********************** +{ + Record* record = Inherit::_getRecord(); + if (record) { + record->add(getSlot("_cell", _cell)); + record->add(getSlot("_name", &_name)); + record->add(getSlot("_arity", &_arity)); + record->add(getSlot("_isGlobal", &_isGlobal)); + record->add(getSlot("_isExternal", &_isExternal)); + record->add(getSlot("_isAutomatic", &_isAutomatic)); + record->add(getSlot("_type", &_type)); + record->add(getSlot("_direction", &_direction)); + record->add(getSlot("_position", &_position)); + record->add(getSlot("_componentsSet", &_componentSet)); + record->add(getSlot("_rubberSet", &_rubberSet)); + record->add(getSlot("_mainName", &_mainName)); + } + return record; +} + +void Net::_toJson( JsonWriter* writer ) const +// ****************************************** +{ + // Inherit::_toJson( writer ); + + // jsonWrite( writer, "_name" , getName() ); + // jsonWrite( writer, "_isGlobal" , isGlobal() ); + // jsonWrite( writer, "_isExternal" , isExternal() ); + // jsonWrite( writer, "_isAutomatic" , isAutomatic() ); + // jsonWrite( writer, "_type" , getType() ); + // jsonWrite( writer, "_direction" , getDirection() ); + // jsonWrite( writer, "+aliases" , getAliases() ); + + // writer->setFlags( JsonWriter::UsePlugReference ); + // jsonWrite( writer, "+componentSet", getComponents() ); + // writer->setFlags( JsonWriter::UsePlugReference ); +} + +JsonObject* Net::getJsonObject(unsigned long flags) +// ************************************************ +{ + return new JsonNet ( flags ); +} + +// **************************************************************************************************** +// Net::Type implementation +// **************************************************************************************************** + +Net::Type::Type(const Code& code) +// ****************************** +: _code(code) +{ } + +Net::Type::Type(const Type& type) +// ****************************** +: _code(type._code) +{ } + +Net::Type::Type(string s) +// ********************** +: _code(UNDEFINED) +{ + if (s == "UNDEFINED") _code = UNDEFINED; + else if (s == "LOGICAL" ) _code = LOGICAL; + else if (s == "CLOCK" ) _code = CLOCK; + else if (s == "POWER" ) _code = POWER; + else if (s == "GROUND" ) _code = GROUND; +} + +Net::Type& Net::Type::operator=(const Type& type) +// ********************************************** +{ + _code = type._code; + return *this; +} + +string Net::Type::_getString() const +// ********************************* +{ + return getString(&_code); +} + +Record* Net::Type::_getRecord() const +// **************************** +{ + Record* record = new Record(getString(this)); + record->add(getSlot("Code", &_code)); + return record; +} + + + +// **************************************************************************************************** +// Net::Direction implementation +// **************************************************************************************************** + +Net::Direction::Direction(const Code& code) +// **************************************** +: _code(code) +{ } + +Net::Direction::Direction(const Direction& direction) +// ************************************************** +: _code(direction._code) +{ } + +Net::Direction::Direction(string s) +// ******************************** +: _code(UNDEFINED) +{ + if (s.size() > 3) { + if (s[0] == 'i') *this |= DirIn; + if (s[0] == 'o') *this |= DirOut; + if (s[0] == 't') *this |= ConnTristate; + if (s[0] == 'w') *this |= ConnWiredOr; + } +} + +Net::Direction& Net::Direction::operator=(const Direction& direction) +// ****************************************************************** +{ + _code = direction._code; + return *this; +} + +Net::Direction& Net::Direction::operator|=(const Direction& direction) +// ****************************************************************** +{ + _code = (Code)((unsigned int)_code | (unsigned int)direction._code); + return *this; +} + +string Net::Direction::_getString() const +// ************************************** +{ + return getString(&_code); +} + +Record* Net::Direction::_getRecord() const +// ********************************* +{ + Record* record = new Record(getString(this)); + record->add(getSlot("Code", &_code)); + return record; +} + + + +// **************************************************************************************************** +// Net::ComponentSet implementation +// **************************************************************************************************** + +Net::ComponentSet::ComponentSet() +// ****************************** +: Inherit() +{ +} + +unsigned Net::ComponentSet::_getHashValue(Component* component) const +// ****************************************************************** +{ + return component->getId() / 8; +} + +Component* Net::ComponentSet::_getNextElement(Component* component) const +// ********************************************************************** +{ + return component->_getNextOfNetComponentSet(); +} + +void Net::ComponentSet::_setNextElement(Component* component, Component* nextComponent) const +// ****************************************************************************************** +{ + component->_setNextOfNetComponentSet(nextComponent); +} + + + +// **************************************************************************************************** +// Net::RubberSet implementation +// **************************************************************************************************** + +Net::RubberSet::RubberSet() +// ************************ +: Inherit() +{ +} + +unsigned Net::RubberSet::_getHashValue(Rubber* rubber) const +// ********************************************************* +{ + return rubber->getId() / 8; +} + +Rubber* Net::RubberSet::_getNextElement(Rubber* rubber) const +// ********************************************************** +{ + return rubber->_getNextOfNetRubberSet(); +} + +void Net::RubberSet::_setNextElement(Rubber* rubber, Rubber* nextRubber) const +// *************************************************************************** +{ + rubber->_setNextOfNetRubberSet(nextRubber); +} + + + +// **************************************************************************************************** +// Net_SlavePlugs implementation +// **************************************************************************************************** + +Net_SlavePlugs::Net_SlavePlugs(const Net* net) +// ******************************************* +: Inherit(), + _net(net) +{ +} + +Net_SlavePlugs::Net_SlavePlugs(const Net_SlavePlugs& slavePlugs) +// ************************************************************* +: Inherit(), + _net(slavePlugs._net) +{ +} + +Net_SlavePlugs& Net_SlavePlugs::operator=(const Net_SlavePlugs& slavePlugs) +// ************************************************************************ +{ + _net = slavePlugs._net; + return *this; +} + +Collection* Net_SlavePlugs::getClone() const +// ************************************************ +{ + return new Net_SlavePlugs(*this); +} + +Locator* Net_SlavePlugs::getLocator() const +// *********************************************** +{ + return new Locator(_net); +} + +string Net_SlavePlugs::_getString() const +// ************************************** +{ + string s = "<" + _TName("Net::SlavePlugs"); + if (_net) s += " " + getString(_net); + s += ">"; + return s; +} + + + +// **************************************************************************************************** +// Net_SlavePlugs::Locator implementation +// **************************************************************************************************** + +Net_SlavePlugs::Locator::Locator(const Net* net) +// ********************************************* +: Inherit(), + _net(net), + _plug(NULL), + _instanceLocator() +{ + if (_net) { + _instanceLocator = _net->getCell()->getSlaveInstances().getLocator(); + while (!_plug && _instanceLocator.isValid()) { + _plug = _instanceLocator.getElement()->getPlug(_net); + _instanceLocator.progress(); + } + } +} + +Net_SlavePlugs::Locator::Locator(const Locator& locator) +// ***************************************************** +: Inherit(), + _net(locator._net), + _plug(locator._plug), + _instanceLocator(locator._instanceLocator) +{ +} + +Net_SlavePlugs::Locator& Net_SlavePlugs::Locator::operator=(const Locator& locator) +// ******************************************************************************** +{ + _net = locator._net; + _plug = locator._plug; + _instanceLocator = locator._instanceLocator; + return *this; +} + +Plug* Net_SlavePlugs::Locator::getElement() const +// ********************************************** +{ + return _plug; +} + +Locator* Net_SlavePlugs::Locator::getClone() const +// ****************************************************** +{ + return new Locator(*this); +} + +bool Net_SlavePlugs::Locator::isValid() const +// ****************************************** +{ + return (_plug != NULL); +} + +void Net_SlavePlugs::Locator::progress() +// ************************************* +{ + if (isValid()) { + _plug = NULL; + while (!_plug && _instanceLocator.isValid()) { + _plug = _instanceLocator.getElement()->getPlug(_net); + _instanceLocator.progress(); + } + } +} + +string Net_SlavePlugs::Locator::_getString() const +// *********************************************** +{ + string s = "<" + _TName("Net::SlavePlugs::Locator"); + if (_net) s += " " + getString(_net); + s += ">"; + return s; +} + + + +// **************************************************************************************************** +// JsonNet implementation +// **************************************************************************************************** + +JsonNet::JsonNet(unsigned long flags) +// ********************************** + : JsonEntity(flags) +{ + addS( "_name" , &Net::_name ); + add ( "_isGlobal" , &Net::_isGlobal ); + add ( "_isExternal" , &Net::_isExternal ); + add ( "_isAutomatic" , &Net::_isAutomatic ); + addS( "_type" , &Net::_type ); + addS( "_direction" , &Net::_direction ); +//addC( "+aliases" , &Net::getAliases ); + add ( "+componentSet", &Net::getComponents ); +} + +string JsonNet::getTypeName() const +// ********************************* +{ return "Net"; } + +JsonNet* JsonNet::clone() const +// **************************** +{ return new JsonNet ( *this ); } + +void JsonNet::toData(JsonStack& stack) +// *********************************** +{ + ltracein(51); + check( stack, "JsonNet::toData" ); + +//unsigned int jsonId = get(stack,"_id"); + Net* net = Net::create ( get(stack,".Cell") , get(stack,"_name") ); + net->setGlobal ( get(stack,"_isGlobal" ) ); + net->setExternal ( get(stack,"_isExternal" ) ); + net->setAutomatic( get(stack,"_isAutomatic") ); + net->setType ( Net::Type (get(stack,"_type")) ); + net->setDirection( Net::Direction(get(stack,"_direction")) ); + + update( stack, net ); + + ltraceout(51); +} + +} // End of Hurricane namespace. + + +// **************************************************************************************************** +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// **************************************************************************************************** diff --git a/hurricane/src/hurricane/grenier/json/Net.h b/hurricane/src/hurricane/grenier/json/Net.h new file mode 100644 index 00000000..e765fb67 --- /dev/null +++ b/hurricane/src/hurricane/grenier/json/Net.h @@ -0,0 +1,363 @@ +// **************************************************************************************************** +// File: ./hurricane/Net.h +// Authors: R. Escassut +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify it under the terms of the GNU +// Lesser General Public License as published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane 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 Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public License along with Hurricane. If +// not, see . +// **************************************************************************************************** + +#ifndef HURRICANE_NET +#define HURRICANE_NET + +#include +#include "hurricane/Entity.h" +#include "hurricane/Nets.h" +#include "hurricane/Component.h" +#include "hurricane/Rubbers.h" +#include "hurricane/Rubber.h" +#include "hurricane/RoutingPads.h" +#include "hurricane/Plugs.h" +#include "hurricane/Pins.h" +#include "hurricane/Contacts.h" +#include "hurricane/Segments.h" +#include "hurricane/Verticals.h" +#include "hurricane/Horizontals.h" +#include "hurricane/Pads.h" +#include "hurricane/IntrusiveSet.h" +#include "hurricane/Path.h" +#include "hurricane/NetAlias.h" + +namespace Hurricane { + + class JsonNet; + +// **************************************************************************************************** +// Net declaration +// **************************************************************************************************** + +class Net : public Entity { +// ********************** + + friend class JsonNet; + +// Types +// ***** + + public: typedef Entity Inherit; + + public: typedef unsigned Arity; + + public: class Type { + // *************** + + public: enum Code {UNDEFINED=0, LOGICAL=1, CLOCK=2, POWER=3, GROUND=4}; + + private: Code _code; + + public: Type(const Code& code = UNDEFINED); + public: Type(const Type& type); + public: Type(string); + + public: Type& operator=(const Type& type); + + public: operator const Code&() const {return _code;}; + + public: const Code& getCode() const {return _code;}; + + public: string _getTypeName() const { return _TName("Net::type"); }; + public: string _getString() const; + public: Record* _getRecord() const; + + }; + + public: class Direction { + // ******************** + + public: enum Code { DirIn = 0x0001 + , DirOut = 0x0002 + , DirUndefined = 0x0000 + , ConnTristate = 0x0100 + , ConnWiredOr = 0x0200 + , UNDEFINED = DirUndefined + , IN = DirIn + , OUT = DirOut + , INOUT = DirIn | DirOut + , TRISTATE = DirOut | ConnTristate + , TRANSCV = DirIn | DirOut | ConnTristate + , WOR_OUT = DirOut | ConnWiredOr + , WOR_INOUT = DirIn | DirOut | ConnWiredOr + , DirMask = DirIn | DirOut | DirUndefined + }; + + private: Code _code; + + public: Direction(const Code& code = UNDEFINED); + public: Direction(const Direction& direction); + public: Direction(string); + + public: Direction& operator =(const Direction& direction); + public: Direction& operator|=(const Direction& direction); + + public: operator const Code&() const {return _code;}; + + public: const Code& getCode() const {return _code;}; + + public: string _getTypeName() const { return _TName("Net::Direction"); }; + public: string _getString() const; + public: Record* _getRecord() const; + + }; + + class ComponentSet : public IntrusiveSet { + // ************************************************ + + public: typedef IntrusiveSet Inherit; + + public: ComponentSet(); + + public: virtual unsigned _getHashValue(Component* component) const; + public: virtual Component* _getNextElement(Component* component) const; + public: virtual void _setNextElement(Component* component, Component* nextComponent) const; + + }; + + class RubberSet : public IntrusiveSet { + // ****************************************** + + public: typedef IntrusiveSet Inherit; + + public: RubberSet(); + + public: virtual unsigned _getHashValue(Rubber* rubber) const; + public: virtual Rubber* _getNextElement(Rubber* rubber) const; + public: virtual void _setNextElement(Rubber* rubber, Rubber* nextRubber) const; + + }; + +// Attributes +// ********** + + private: Cell* _cell; + private: Name _name; + private: Arity _arity; + private: bool _isGlobal; + private: bool _isExternal; + private: bool _isAutomatic; + private: Type _type; + private: Direction _direction; + private: Point _position; + private: ComponentSet _componentSet; + private: RubberSet _rubberSet; + private: Net* _nextOfCellNetMap; + private: NetMainName _mainName; + +// Constructors +// ************ + + protected: Net(Cell* cell, const Name& name); + + public: static Net* create(Cell* cell, const Name& name); + +// Accessors +// ********* + + public: virtual Cell* getCell() const {return _cell;}; + public: virtual Box getBoundingBox() const; + public: const Name& getName() const {return _name;}; + public: const NetMainName* getMainName() const { return &_mainName; } + public: const Arity& getArity() const {return _arity;}; + public: const Type& getType() const {return _type;}; + public: const Direction& getDirection() const {return _direction;}; + public: const Point& getPosition() const {return _position;}; + public: const DbU::Unit& getX() const {return _position.getX();}; + public: const DbU::Unit& getY() const {return _position.getY();}; + public: Components getComponents() const {return _componentSet.getElements();}; + public: Rubbers getRubbers() const {return _rubberSet.getElements();}; + public: RoutingPads getRoutingPads() const; + public: Plugs getPlugs() const; + public: Pins getPins() const; + public: Contacts getContacts() const; + public: Segments getSegments() const; + public: Verticals getVerticals() const; + public: Horizontals getHorizontals() const; + public: Pads getPads() const; + public: Plugs getSlavePlugs() const; + public: Plugs getConnectedSlavePlugs() const; + public: Plugs getUnconnectedSlavePlugs() const; + public: Aliases getAliases() const { return new AliasList(this); }; + +// Filters +// ******* + + public: static NetFilter getIsCellNetFilter(); + public: static NetFilter getIsDeepNetFilter(); + public: static NetFilter getIsGlobalFilter(); + public: static NetFilter getIsExternalFilter(); + public: static NetFilter getIsInternalFilter(); + public: static NetFilter getIsClockFilter(); + public: static NetFilter getIsSupplyFilter(); + public: static NetFilter getIsPowerFilter(); + public: static NetFilter getIsGroundFilter(); + +// Predicates +// ********** + + public: virtual bool isDeepNet () const {return false;}; + public: bool isGlobal () const {return _isGlobal;}; + public: bool isExternal () const {return _isExternal;}; + public: bool isAutomatic() const {return _isAutomatic;}; + public: bool isLogical () const {return (_type == Type::LOGICAL);}; + public: bool isClock () const {return (_type == Type::CLOCK);}; + public: bool isPower () const {return (_type == Type::POWER);}; + public: bool isGround () const {return (_type == Type::GROUND);}; + public: bool isSupply () const {return (isPower() || isGround());}; + +// Updators +// ******** + + public: void setName(const Name& name); + public: void setArity(const Arity& arity); + public: void setGlobal(bool isGlobal); + public: void setExternal(bool isExternal); + public: void setAutomatic(bool isAutomatic); + public: void setType(const Type& type); + public: void setDirection(const Direction& direction); + public: void setPosition(const Point& position); + public: void materialize(); + public: void unmaterialize(); + public: bool addAlias(const Name& name); + public: bool removeAlias(const Name& name); + public: void merge(Net* net); + public: Net* getClone(Cell* cloneCell); + +// Others +// ****** + + protected: virtual void _postCreate(); + protected: virtual void _preDestroy(); + + public: virtual void _toJson ( JsonWriter* ) const; + public: static JsonObject* getJsonObject(unsigned long flags); + public: virtual string _getTypeName() const {return _TName("Net");}; + public: virtual string _getString() const; + public: virtual Record* _getRecord() const; + public: NetMainName& _getMainName() { return _mainName; } + public: ComponentSet& _getComponentSet() {return _componentSet;}; + public: RubberSet& _getRubberSet() {return _rubberSet;}; + public: Net* _getNextOfCellNetMap() const {return _nextOfCellNetMap;}; + + public: void _setNextOfCellNetMap(Net* net) {_nextOfCellNetMap = net;}; + +}; + +class JsonNet : public JsonEntity { +// ******************************** + + public: JsonNet(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonNet* clone() const; + public: virtual void toData(JsonStack&); +}; + +} // End of Hurricane namespace. + + +// ------------------------------------------------------------------- +// Inspector Support for : Net::Type::Code*". + +template<> +inline std::string getString + ( const Hurricane::Net::Type::Code* object ) + { + switch ( *object ) { + case Hurricane::Net::Type::UNDEFINED: return "UNDEFINED"; + case Hurricane::Net::Type::LOGICAL: return "LOGICAL"; + case Hurricane::Net::Type::CLOCK: return "CLOCK"; + case Hurricane::Net::Type::POWER: return "POWER"; + case Hurricane::Net::Type::GROUND: return "GROUND"; + } + return "ABNORMAL"; + } + +template<> +inline Hurricane::Record* getRecord + ( const Hurricane::Net::Type::Code* object ) + { + Hurricane::Record* record = new Hurricane::Record(getString(object)); + record->add(getSlot("Code", (unsigned int*)object)); + return record; + } + + +// ------------------------------------------------------------------- +// Inspector Support for : "const Net::Direction::Code*". + +template<> +inline std::string getString + ( const Hurricane::Net::Direction::Code* object ) + { + std::ostringstream s; + s << (((*object) & Hurricane::Net::Direction::DirIn ) ? 'i' : '-'); + s << (((*object) & Hurricane::Net::Direction::DirOut ) ? 'o' : '-'); + s << (((*object) & Hurricane::Net::Direction::ConnTristate) ? 't' : '-'); + s << (((*object) & Hurricane::Net::Direction::ConnWiredOr ) ? 'w' : '-'); + + switch ( (int)*object ) { + case Hurricane::Net::Direction::UNDEFINED: s << " (UNDEFINED)"; break; + case Hurricane::Net::Direction::IN: s << " (IN)"; break; + case Hurricane::Net::Direction::OUT: s << " (OUT)"; break; + case Hurricane::Net::Direction::INOUT: s << " (INOUT)"; break; + case Hurricane::Net::Direction::TRISTATE: s << " (TRISTATE)"; break; + case Hurricane::Net::Direction::TRANSCV: s << " (TRANSCV)"; break; + case Hurricane::Net::Direction::WOR_OUT: s << " (WOR_OUT)"; break; + case Hurricane::Net::Direction::WOR_INOUT: s << " (WOR_INOUT)"; break; + } + return s.str(); + } + +template<> +inline Hurricane::Record* getRecord + ( const Hurricane::Net::Direction::Code* object ) + { + Hurricane::Record* record = new Hurricane::Record(getString(object)); + record->add(getSlot("Code", (unsigned int*)object)); + return record; + } + + +INSPECTOR_P_SUPPORT(Hurricane::Net); +INSPECTOR_P_SUPPORT(Hurricane::Net::ComponentSet); +INSPECTOR_P_SUPPORT(Hurricane::Net::RubberSet); +INSPECTOR_PV_SUPPORT(Hurricane::Net::Type); +INSPECTOR_PV_SUPPORT(Hurricane::Net::Direction); +IOSTREAM_POINTER_SUPPORT(Hurricane::Net::Type::Code); +IOSTREAM_VALUE_SUPPORT(Hurricane::Net::Type::Code); +IOSTREAM_POINTER_SUPPORT(Hurricane::Net::Direction::Code); +IOSTREAM_VALUE_SUPPORT(Hurricane::Net::Direction::Code); + + +namespace Hurricane { + +// Force SlotTemplate<> expansion on Net* type. +// Because sometimes it didn't happens (?). + const SlotTemplate dummyNetSlot ( string("dummyNetSlot"), NULL ); + +} + +#endif // HURRICANE_NET + + +// **************************************************************************************************** +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved +// **************************************************************************************************** diff --git a/hurricane/src/hurricane/hurricane/Box.h b/hurricane/src/hurricane/hurricane/Box.h index e8b18f5f..37c37337 100644 --- a/hurricane/src/hurricane/hurricane/Box.h +++ b/hurricane/src/hurricane/hurricane/Box.h @@ -24,8 +24,6 @@ namespace Hurricane { - - // **************************************************************************************************** // Box declaration // **************************************************************************************************** @@ -36,7 +34,6 @@ class Box { // Attributes // ********** - private: DbU::Unit _xMin; private: DbU::Unit _yMin; private: DbU::Unit _xMax; @@ -125,10 +122,20 @@ class Box { public: string _getTypeName() const { return _TName("Box"); }; public: string _getString() const; public: Record* _getRecord() const; + public: void toJson(JsonWriter*) const; }; +class JsonBox : public JsonObject { +// ******************************** + + public: JsonBox(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonBox* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index 0ea136a4..55107f02 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -23,6 +23,7 @@ #include #include "hurricane/Flags.h" #include "hurricane/Observer.h" +#include "hurricane/Signature.h" #include "hurricane/Relation.h" #include "hurricane/Pathes.h" #include "hurricane/Entity.h" @@ -54,7 +55,6 @@ namespace Hurricane { class Library; class BasicLayer; - typedef multimap SlaveEntityMap; @@ -302,6 +302,9 @@ class Cell : public Entity { public: void _changeQuadTree(Cell*); public: void _setShuntedPath(Path path) { _shuntedPath=path; } + public: virtual void _toJson(JsonWriter*) const; + public: virtual void _toJsonCollections(JsonWriter*) const; + // Constructors // ************ @@ -313,9 +316,11 @@ class Cell : public Entity { public: virtual Cell* getCell() const {return (Cell*)this;}; public: virtual Box getBoundingBox() const; public: Library* getLibrary() const {return _library;}; + public: string getHierarchicalName() const; public: const Name& getName() const {return _name;}; public: const Flags& getFlags() const { return _flags; } public: Path getShuntedPath() const { return _shuntedPath; } + public: Entity* getEntity(const Signature&) const; public: Instance* getInstance(const Name& name) const {return _instanceMap.getElement(name);}; public: Instances getInstances() const {return _instanceMap.getElements();}; public: Instances getPlacedInstances() const; @@ -441,6 +446,15 @@ inline Cell::ClonedSet::ClonedSet ( const ClonedSet& other ) { } +class JsonCell : public JsonEntity { +// ********************************* + + public: JsonCell(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonCell* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Collection.h b/hurricane/src/hurricane/hurricane/Collection.h index 0064f0ab..805d5e68 100644 --- a/hurricane/src/hurricane/hurricane/Collection.h +++ b/hurricane/src/hurricane/hurricane/Collection.h @@ -27,6 +27,7 @@ namespace Hurricane { template class GenericCollection; template class SubTypeCollection; +template class NotSubTypeCollection; template class SubSetCollection; @@ -113,6 +114,12 @@ template class Collection { return getSubSet().getSubSet(filter); } + public: template GenericCollection getNotSubSet() const + // **************************************************************************** + { + return NotSubTypeCollection(this); + } + // Predicates // ********** @@ -627,6 +634,171 @@ template class SubTypeCollection : public Collection< }; +// **************************************************************************************************** +// NotSubTypeCollection declaration +// **************************************************************************************************** + +template class NotSubTypeCollection : public Collection { +// ****************************************************************************************** + +// Types +// ***** + + public: typedef Collection Inherit; + + public: class Locator : public Hurricane::Locator { + // ******************************************************* + + // Types + // ***** + + public: typedef Hurricane::Locator Inherit; + + // Attributes + // ********** + + private: GenericLocator _locator; + + // Constructors + // ************ + + public: Locator(const GenericCollection& collection) + // ******************************************************** + : Inherit(), + _locator(collection.getLocator()) + { + while (_locator.isValid() && dynamic_cast(_locator.getElement())) + _locator.progress(); + } + + public: Locator(const GenericLocator& genericLocator) + // ******************************************************** + : Inherit(), + _locator(genericLocator.getClone()) + { + while (_locator.isValid() && !dynamic_cast(_locator.getElement())) + _locator.progress(); + } + + // Accessors + // ********* + + public: virtual SubType getElement() const + // *************************************** + { + return (_locator.isValid()) ? (SubType)_locator.getElement() : SubType(); + } + + public: virtual Hurricane::Locator* getClone() const + // ********************************************************** + { + return new Locator(_locator); + } + + public: virtual Hurricane::Locator* getLocator() // 21-10-03 + // ************************************************* + { + return dynamic_cast*> ( + _locator.getLocator()->getLocator() ); + } + + + // Predicates + // ********** + + public: virtual bool isValid() const + // ********************************* + { + return _locator.isValid(); + } + + // Updators + // ******** + + public: virtual void progress() + // **************************** + { + if (_locator.isValid()) { + do { + _locator.progress(); + } while (_locator.isValid() && !dynamic_cast(_locator.getElement())); + } + } + + }; + +// Attributes +// ********** + + private: GenericCollection _collection; + +// Constructors +// ************ + + public: NotSubTypeCollection() + // ******************** + : Inherit(), + _collection() + { + } + + public: NotSubTypeCollection(const Collection* collection) + // ********************************************************** + : Inherit(), + _collection(collection->getClone()) + { + } + + public: NotSubTypeCollection(const GenericCollection& collection) + // ***************************************************************** + : Inherit(), + _collection(collection) + { + } + + public: NotSubTypeCollection(const NotSubTypeCollection& subTypeCollection) + // ****************************************************************** + : Inherit(), + _collection(subTypeCollection._collection) + { + } + +// Operators +// ********* + + public: NotSubTypeCollection& operator=(const NotSubTypeCollection& subTypeCollection) + // ***************************************************************************** + { + _collection = subTypeCollection._collection; + return *this; + } + +// Accessors +// ********* + + public: virtual Collection* getClone() const + // ************************************************** + { + return new NotSubTypeCollection(_collection); + } + + public: virtual Hurricane::Locator* getLocator() const + // ************************************************************ + { + return new Locator(_collection); + } + +// Accessors +// ********* + + public: virtual string _getString() const + // ************************************** + { + return "<" + _TName("NotSubTypeCollection") + " " + getString(_collection) + ">"; + } + +}; + // **************************************************************************************************** // SubSetCollection implementation @@ -909,7 +1081,6 @@ inline ForEachIterator& ForEachIterator::operator++ (int) for ( ForEachIterator iterator(collection); iterator.isValid() ; iterator++ ) - } // End of Hurricane namespace. @@ -932,6 +1103,24 @@ template inline Hurricane::Record* getRecord ( const Hurricane::C { return collection->_getRecord(); } +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::GenericCollection collection ) +{ + if (Hurricane::inltrace(50)) + std::cerr << Hurricane::tab + << "jsonWrite< GenericCollection<" << Hurricane::demangle(typeid(Type).name()) + << "> >(w,key,coll)" << " key:\"" << key << "\"" << std::endl; + Hurricane::ltracein(50); + + w->key( key ); + w->startArray(); + for ( Type element : collection ) jsonWrite( w, element ); + w->endArray(); + + Hurricane::ltraceout(50); +} + + #include "hurricane/MultisetCollection.h" #include "hurricane/SetCollection.h" #include "hurricane/MapCollection.h" diff --git a/hurricane/src/hurricane/hurricane/Commons.h b/hurricane/src/hurricane/hurricane/Commons.h index 9825b625..7ccabc15 100644 --- a/hurricane/src/hurricane/hurricane/Commons.h +++ b/hurricane/src/hurricane/hurricane/Commons.h @@ -740,6 +740,8 @@ inline Hurricane::Record* getRecord ( const std::multiset* s ) #include "hurricane/Slot.h" #include "hurricane/Tabulation.h" +#include "hurricane/JsonWriter.h" +#include "hurricane/JsonReader.h" #endif // HURRICANE_COMMONS_H diff --git a/hurricane/src/hurricane/hurricane/Component.h b/hurricane/src/hurricane/hurricane/Component.h index 232b1e1d..b330fd21 100644 --- a/hurricane/src/hurricane/hurricane/Component.h +++ b/hurricane/src/hurricane/hurricane/Component.h @@ -33,7 +33,6 @@ class Rubber; class Layer; - // **************************************************************************************************** // Component declaration // **************************************************************************************************** @@ -59,8 +58,9 @@ class Component : public Go { public: virtual bool isMaster() const {return true;}; - public: virtual string _getTypeName() const { return _TName("Component::BodyHook"); }; + public: virtual string _getTypeName() const { return "Component::BodyHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; @@ -101,6 +101,7 @@ class Component : public Go { public: virtual void materialize(); public: virtual void unmaterialize(); public: virtual void invalidate(bool propagateFlag = true); + public: virtual void forceId(unsigned int id); // Filters // ******* @@ -114,6 +115,8 @@ class Component : public Go { protected: virtual void _preDestroy(); + public: virtual void _toJson ( JsonWriter* ) const; + public: virtual void _toJsonSignature(JsonWriter*) const; public: virtual string _getString() const; public: virtual Record* _getRecord() const; public: Component* _getNextOfNetComponentSet() const {return _nextOfNetComponentSet;}; @@ -128,6 +131,12 @@ class Component : public Go { double getArea ( Component* component ); +class JsonComponent : public JsonEntity { +// ************************************ + + public: JsonComponent(unsigned long flags); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Contact.h b/hurricane/src/hurricane/hurricane/Contact.h index 942c5b29..93b91c44 100644 --- a/hurricane/src/hurricane/hurricane/Contact.h +++ b/hurricane/src/hurricane/hurricane/Contact.h @@ -26,7 +26,6 @@ namespace Hurricane { - // **************************************************************************************************** // Contact declaration // **************************************************************************************************** @@ -52,8 +51,9 @@ class Contact : public Component { public: virtual bool isMaster() const {return false;}; - public: virtual string _getTypeName() const { return _TName("Contact::AnchorHook"); }; + public: virtual string _getTypeName() const { return "Contact::AnchorHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; // Attributes @@ -141,6 +141,7 @@ class Contact : public Component { protected: virtual void _preDestroy(); + public: virtual void _toJson(JsonWriter*) const; public: virtual string _getTypeName() const {return _TName("Contact");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -148,6 +149,15 @@ class Contact : public Component { }; +class JsonContact : public JsonComponent { +// *************************************** + + public: JsonContact(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonContact* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/DBo.h b/hurricane/src/hurricane/hurricane/DBo.h index 197ae473..44714b2b 100644 --- a/hurricane/src/hurricane/hurricane/DBo.h +++ b/hurricane/src/hurricane/hurricane/DBo.h @@ -1,4 +1,3 @@ - // -*- C++ -*- // // Copyright (c) BULL S.A. 2000-2015, All Rights Reserved @@ -19,12 +18,7 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -32,14 +26,11 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./hurricane/DBo.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#ifndef __HURRICANE_DBO__ -#define __HURRICANE_DBO__ +#ifndef HURRICANE_DBO_H +#define HURRICANE_DBO_H #include "hurricane/DBos.h" #include "hurricane/Name.h" @@ -52,40 +43,39 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "Hurricane::DBo". - class DBo { - public: - // Methods. - virtual void destroy(); - inline set& _getPropertySet (); - void _onDestroyed ( Property* property ); - Property* getProperty ( const Name& ) const; - Properties getProperties () const; - inline bool hasProperty () const; - void put ( Property* ); - void remove ( Property* ); - void removeProperty ( const Name& ); - void clearProperties (); - // Hurricane Managment. - virtual string _getTypeName () const; - virtual string _getString () const; - virtual Record* _getRecord () const; - - private: - // Internal: Attributes. - mutable set _propertySet; - - protected: - // Internal: Constructors & Destructors. - DBo (); - virtual ~DBo (); - virtual void _postCreate (); - virtual void _preDestroy (); - private: - // Forbidden: Copies. - DBo ( const DBo& ); - DBo& operator= ( const DBo& ); + virtual void destroy (); + inline set& _getPropertySet (); + void _onDestroyed ( Property* property ); + Property* getProperty ( const Name& ) const; + Properties getProperties () const; + inline bool hasProperty () const; + void put ( Property* ); + void remove ( Property* ); + void removeProperty ( const Name& ); + void clearProperties (); + virtual string _getTypeName () const; + virtual string _getString () const; + virtual Record* _getRecord () const; + virtual void _toJson ( JsonWriter* ) const; + virtual void _toJsonCollections ( JsonWriter* ) const; + virtual void _toJsonSignature ( JsonWriter* ) const; + void toJson ( JsonWriter* ) const; + void toJsonSignature ( JsonWriter* ) const; + + private: + mutable set _propertySet; + + protected: + DBo (); + virtual ~DBo (); + virtual void _postCreate (); + virtual void _preDestroy (); + + private: + DBo ( const DBo& ); + DBo& operator= ( const DBo& ); }; @@ -94,10 +84,17 @@ namespace Hurricane { inline bool DBo::hasProperty () const { return !_propertySet.empty(); } -} // End of Hurricane namespace. +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDBo". + class JsonDBo : public JsonObject { + public: + JsonDBo ( unsigned int flags ); +}; + + +} // Hurricane namespace. INSPECTOR_P_SUPPORT(Hurricane::DBo); - -#endif // __HURRICANE_DBO__ +#endif // HURRICANE_DBO_H diff --git a/hurricane/src/hurricane/hurricane/DataBase.h b/hurricane/src/hurricane/hurricane/DataBase.h index 81054082..efd1bc22 100644 --- a/hurricane/src/hurricane/hurricane/DataBase.h +++ b/hurricane/src/hurricane/hurricane/DataBase.h @@ -20,11 +20,13 @@ #ifndef HURRICANE_DATA_BASE #define HURRICANE_DATA_BASE +#include #include "hurricane/DBo.h" #include "hurricane/DbU.h" namespace Hurricane { +class Cell; class Library; class Technology; @@ -37,8 +39,6 @@ class Technology; class DataBase : public DBo { // ************************ -# if !defined(__DOXYGEN_PROCESSOR__) - // Types // ***** @@ -50,6 +50,7 @@ class DataBase : public DBo { private: static DataBase* _db; private: Technology* _technology; private: Library* _rootLibrary; + private: function _cellLoader; // Constructors // ************ @@ -69,8 +70,7 @@ class DataBase : public DBo { public: void _setTechnology(Technology* technology) {_technology = technology;}; public: void _setRootLibrary(Library* rootLibrary) {_rootLibrary = rootLibrary;}; - -# endif + public: void _setCellLoader(function loader) { _cellLoader=loader; }; public: static DataBase* create(); @@ -79,6 +79,8 @@ class DataBase : public DBo { public: Technology* getTechnology() const {return _technology;}; public: Library* getRootLibrary() const {return _rootLibrary;}; + public: Library* getLibrary(string) const; + public: Cell* getCell(string) const; public: static DataBase* getDB(); }; diff --git a/hurricane/src/hurricane/hurricane/DbU.h b/hurricane/src/hurricane/hurricane/DbU.h index 11b03828..18a19eb1 100644 --- a/hurricane/src/hurricane/hurricane/DbU.h +++ b/hurricane/src/hurricane/hurricane/DbU.h @@ -180,4 +180,8 @@ namespace Hurricane { } // End of Hurricane namespace. +// inline void jsonWriteDbU ( JsonWriter* w, const std::string& key, long* value ) +// { w->key( key ); w->write( value ); } + + #endif // HURRICANE_DBU_H diff --git a/hurricane/src/hurricane/hurricane/DeepNet.h b/hurricane/src/hurricane/hurricane/DeepNet.h index e41c0d0a..6ff462d3 100644 --- a/hurricane/src/hurricane/hurricane/DeepNet.h +++ b/hurricane/src/hurricane/hurricane/DeepNet.h @@ -36,45 +36,47 @@ #include "hurricane/HyperNet.h" #include "hurricane/Occurrence.h" - namespace Hurricane { - class DeepNet : public Net { - // Attributes. +// ------------------------------------------------------------------- +// Class : "DeepNet". + + class DeepNet : public Net { + public: + typedef Net Inherit; + public: + static DeepNet* create ( HyperNet& hyperNet ); + inline Occurrence getRootNetOccurrence () const; + virtual bool isDeepNet () const { return true; }; + size_t _createRoutingPads ( unsigned int flags=0 ); + virtual Record* _getRecord () const; + virtual string _getTypeName () const { return "DeepNet"; }; + virtual void _toJson ( JsonWriter* ) const; + protected: + DeepNet ( Occurrence& netOccurrence ); protected: Occurrence _netOccurrence; - // Constructors. - protected: - DeepNet ( Occurrence& netOccurrence ); + }; - // Inspector Management. + + inline Occurrence DeepNet::getRootNetOccurrence() const { return _netOccurrence; } + + Net* getDeepNet(HyperNet& hyperNet); + + +// ------------------------------------------------------------------- +// Class : "JsonDeepNet". + + class JsonDeepNet : public JsonNet { public: - virtual Record* _getRecord () const; - virtual string _getTypeName() const { return "DeepNet"; }; - - // Constructors. - public: - static DeepNet* create ( HyperNet& hyperNet ); - - // Accessors. - public: - inline Occurrence getRootNetOccurrence () const; - - // Predicates. - public: - virtual bool isDeepNet () const { return true; }; - - // Internal Modifiers. - public: - size_t _createRoutingPads ( unsigned int flags=0 ); - -}; - -inline Occurrence DeepNet::getRootNetOccurrence() const { return _netOccurrence; } - -Net* getDeepNet(HyperNet& hyperNet); + JsonDeepNet ( unsigned long flags ); + virtual ~JsonDeepNet (); + virtual string getTypeName () const; + virtual JsonDeepNet* clone ( unsigned long ) const; + virtual void toData ( JsonStack&); + }; } // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/DesignBlob.h b/hurricane/src/hurricane/hurricane/DesignBlob.h new file mode 100644 index 00000000..c5c9adaf --- /dev/null +++ b/hurricane/src/hurricane/hurricane/DesignBlob.h @@ -0,0 +1,60 @@ +// -*- mode: C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2016-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/DesignBlob.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_DESIGN_BLOB_H +#define HURRICANE_DESIGN_BLOB_H + +#include "hurricane/Commons.h" + + +namespace Hurricane { + + class Cell; + +// ------------------------------------------------------------------- +// Classes : "DesignBlob". + + class DesignBlob { + public: + inline DesignBlob ( Cell* ); + inline Cell* getTopCell () const; + void toJson ( JsonWriter* ) const; + inline std::string _getTypeName () const; + private: + Cell* _topCell; + }; + + + inline DesignBlob::DesignBlob ( Cell* topCell ) : _topCell(topCell) { } + inline Cell* DesignBlob::getTopCell () const { return _topCell; } + inline std::string DesignBlob::_getTypeName () const { return "DesignBlob"; } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonDesignBlob". + + class JsonDesignBlob : public JsonObject { + public: + JsonDesignBlob ( unsigned long flags ); + virtual std::string getTypeName () const; + virtual JsonDesignBlob* clone ( unsigned long ) const; + virtual void toData ( JsonStack& ); +}; + + +} // Hurricane namespace. + +#endif diff --git a/hurricane/src/hurricane/hurricane/Entity.h b/hurricane/src/hurricane/hurricane/Entity.h index b3c5679f..2fe01aec 100644 --- a/hurricane/src/hurricane/hurricane/Entity.h +++ b/hurricane/src/hurricane/hurricane/Entity.h @@ -35,26 +35,38 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "Hurricane::Entity". - class Entity : public DBo { public: typedef DBo Inherit; public: - static unsigned int getIdCounter (); + enum Flags { ForcedIdMode = (1<<0) + , NextIdSet = (1<<1) + }; public: - inline unsigned int getId () const; - virtual Cell* getCell () const = 0; - virtual Box getBoundingBox() const = 0; - virtual string _getString () const; - virtual Record* _getRecord () const; - Quark* _getQuark ( SharedPath* sharedPath = NULL ) const; - protected: - Entity (); - virtual void _preDestroy (); + static unsigned int getIdCounter (); + unsigned int getNextId (); + static void setNextId ( unsigned int ); + static bool inForcedIdMode (); + static void enableForcedIdMode (); + static void disableForcedIdMode (); + public: + inline unsigned int getId () const; + virtual Cell* getCell () const = 0; + virtual Box getBoundingBox () const = 0; + void setId ( unsigned int ); + virtual void _toJson ( JsonWriter* ) const; + virtual string _getString () const; + virtual Record* _getRecord () const; + Quark* _getQuark ( SharedPath* sharedPath = NULL ) const; + protected: + Entity (); + virtual void _preDestroy (); private: - static unsigned int _idCounter; - unsigned int _id; + static unsigned long _flags; + static unsigned int _nextId; + static unsigned int _idCounter; + unsigned int _id; public: struct CompareById : public std::binary_function { @@ -68,6 +80,24 @@ namespace Hurricane { { return ((lhs)?lhs->getId():0) < ((rhs)?rhs->getId():0); } +// ------------------------------------------------------------------- +// Class : "Hurricane::JsonEntity". + + class JsonEntity : public JsonDBo { + public: + JsonEntity ( unsigned long flags ); + template inline void update ( JsonStack&, T ); +}; + + + template inline void JsonEntity::update ( JsonStack& stack, T hobject ) + { + unsigned int jsonId = get(stack,"_id"); + + JsonObject::update( stack, hobject ); + stack.addEntity( jsonId, hobject ); + } + } // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Hook.h b/hurricane/src/hurricane/hurricane/Hook.h index 8cc8de2d..c9f1ce57 100644 --- a/hurricane/src/hurricane/hurricane/Hook.h +++ b/hurricane/src/hurricane/hurricane/Hook.h @@ -35,9 +35,12 @@ class Component; class Hook { // ********* + typedef Hook* (*compToHook_t)(Component*); + // Attributes // ********** + private: static map _compToHookMap; private: Hook* _nextHook; // Constructors @@ -95,13 +98,16 @@ class Hook { // Others // ****** + public: static void addCompToHook(const string&, compToHook_t ); + public: static Hook* compToHook(const string& tname, Component* ); + public: string toJson() const; + public: virtual string _getTypeName() const = 0; public: virtual string _getString() const = 0; public: virtual Record* _getRecord() const; }; - } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Horizontal.h b/hurricane/src/hurricane/hurricane/Horizontal.h index d2e3c1d0..2a2cdcd7 100644 --- a/hurricane/src/hurricane/hurricane/Horizontal.h +++ b/hurricane/src/hurricane/hurricane/Horizontal.h @@ -104,6 +104,8 @@ class Horizontal : public Segment { // Others // ****** + public: virtual void _toJson(JsonWriter*) const; + public: static JsonObject* getJsonObject(unsigned long flags); public: virtual string _getTypeName() const {return _TName("Horizontal");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -111,6 +113,15 @@ class Horizontal : public Segment { }; +class JsonHorizontal : public JsonSegment { +// **************************************** + + public: JsonHorizontal(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonHorizontal* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Instance.h b/hurricane/src/hurricane/hurricane/Instance.h index 538714b7..19cab0d0 100644 --- a/hurricane/src/hurricane/hurricane/Instance.h +++ b/hurricane/src/hurricane/hurricane/Instance.h @@ -51,6 +51,7 @@ class Instance : public Go { public: PlacementStatus(const Code& code = UNPLACED); public: PlacementStatus(const PlacementStatus& placementstatus); + public: PlacementStatus(string); public: PlacementStatus& operator=(const PlacementStatus& placementstatus); @@ -178,6 +179,8 @@ class Instance : public Go { public: virtual string _getTypeName() const {return _TName("Instance");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; + public: virtual void _toJson(JsonWriter*) const; + public: virtual void _toJsonCollections(JsonWriter*) const; public: PlugMap& _getPlugMap() {return _plugMap;}; public: SharedPath* _getSharedPath(const SharedPath* tailSharedPath) const {return _sharedPathMap.getElement(tailSharedPath);} public: SharedPathes _getSharedPathes() const {return _sharedPathMap.getElements();}; @@ -191,6 +194,15 @@ class Instance : public Go { }; +class JsonInstance : public JsonEntity { +// ************************************* + + public: JsonInstance(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonInstance* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. @@ -245,6 +257,11 @@ INSPECTOR_P_SUPPORT(Hurricane::Instance::PlacementStatus); INSPECTOR_P_SUPPORT(Hurricane::Instance::PlugMap); INSPECTOR_P_SUPPORT(Hurricane::Instance::SharedPathMap); +inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane::Instance::PlacementStatus& status ) +{ + w->key( key ); + w->write( getString(status.getCode()) ); +} #endif // HURRICANE_INSTANCE diff --git a/hurricane/src/hurricane/hurricane/Interval.h b/hurricane/src/hurricane/hurricane/Interval.h index e62c2841..7ee2f263 100644 --- a/hurricane/src/hurricane/hurricane/Interval.h +++ b/hurricane/src/hurricane/hurricane/Interval.h @@ -108,6 +108,15 @@ class Interval { } // End of Hurricane namespace. +inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane::Interval* interval ) +{ + w->key( key ); + w->startArray(); + w->write( &interval->getVMin() ); + w->write( &interval->getVMax() ); + w->endArray(); +} + INSPECTOR_PV_SUPPORT(Hurricane::Interval); diff --git a/hurricane/src/hurricane/hurricane/IntrusiveMap.h b/hurricane/src/hurricane/hurricane/IntrusiveMap.h index cffd7474..bb2cd8ca 100644 --- a/hurricane/src/hurricane/hurricane/IntrusiveMap.h +++ b/hurricane/src/hurricane/hurricane/IntrusiveMap.h @@ -449,6 +449,13 @@ template class IntrusiveMap { }; + template + inline GenericCollection getCollection(const IntrusiveMap& intrusiveMap) + // ******************************************************************************************** + { + return intrusiveMap.getElements(); + } + } // End of Hurricane namespace. @@ -470,6 +477,15 @@ inline Hurricane::Record* getRecord ( const Hurricane::IntrusiveMap { return intrusiveMap->_getRecord(); } +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::IntrusiveMap* intrusiveMap ) +{ + w->key( key ); + w->startArray(); + for ( Element* element : intrusiveMap->getElements() ) jsonWrite( w, element ); + w->endArray(); +} + #endif // HURRICANE_INTRUSIVE_MAP diff --git a/hurricane/src/hurricane/hurricane/IntrusiveSet.h b/hurricane/src/hurricane/hurricane/IntrusiveSet.h index 97b9f04b..7f245de7 100644 --- a/hurricane/src/hurricane/hurricane/IntrusiveSet.h +++ b/hurricane/src/hurricane/hurricane/IntrusiveSet.h @@ -470,6 +470,11 @@ template class IntrusiveSet { }; + template + inline GenericCollection getCollection(const IntrusiveSet& intrusiveSet) + // **************************************************************************************** + { return intrusiveSet.getElements(); } + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/JsonReader.h b/hurricane/src/hurricane/hurricane/JsonReader.h new file mode 100644 index 00000000..16f62490 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/JsonReader.h @@ -0,0 +1,439 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/JsonReader.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_JSON_READER_H +#define HURRICANE_JSON_READER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Hurricane { + + class Hook; + class Entity; + class Cell; + class Component; + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonStack; + class JsonArray { }; + + +// ------------------------------------------------------------------- +// Class : "JsonAttribute". + + class JsonAttribute { + public: + inline JsonAttribute ( const std::string& key, std::type_index tid ); + inline std::string key () const; + inline std::type_index tid () const; + private: + std::string _key; + std::type_index _tid; + }; + + inline JsonAttribute::JsonAttribute ( const std::string& key, std::type_index tid ) : _key(key), _tid(tid) { } + inline std::string JsonAttribute::key () const { return _key; } + inline std::type_index JsonAttribute::tid () const { return _tid; } + + +// ------------------------------------------------------------------- +// Class : "JsonObject". + + class JsonObject { + public: + JsonObject ( unsigned long flags ); + virtual ~JsonObject (); + virtual bool isDummy () const; + virtual std::string getTypeName () const = 0; + inline std::string getStackName () const; + bool check ( JsonStack&, string fname ) const; + void print ( std::ostream& ) const; + bool has ( const std::string& key ) const; + void add ( const std::string& key, std::type_index tid ); + void remove ( const std::string& key ); + template inline T get ( JsonStack&, const std::string& key ) const; + inline void copyAttrs ( const JsonObject*, bool reset=false ); + inline void clear (); + inline std::string getName () const; + inline void setName ( const string& ); + template inline T& getObject () const; + template inline void setObject ( T& ) ; + inline bool isBound () const; + virtual JsonObject* clone ( unsigned long flags ) const = 0; + template void toJson ( JsonWriter*, C* object ) const; + virtual void toData ( JsonStack& ); + unsigned int presetId ( JsonStack& ); + template inline void update ( JsonStack&, T ); + inline JsonObject* setFlags ( unsigned long mask ); + inline JsonObject* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + protected: + unsigned long _flags; + std::string _name; + std::vector _stackeds; + std::vector _attributes; + std::vector _collections; + boost::any _object; + }; + + + inline bool JsonObject::isBound () const { return not _object.empty(); } + inline std::string JsonObject::getName () const { return _name; } + inline void JsonObject::setName ( const string& name ) { _name=name; } + inline JsonObject* JsonObject::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonObject* JsonObject::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonObject::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + inline std::string JsonObject::getStackName () const + { return (_name.empty()) ? std::string(".")+getTypeName(): _name; } + + template inline T& JsonObject::getObject () const + { return boost::any_cast(_object); } + + template inline void JsonObject::setObject ( T& t ) + { _object = t; } + + inline void JsonObject::copyAttrs ( const JsonObject* other, bool reset ) + { + if (reset) _attributes.clear(); + for ( size_t i=0 ; i_attributes.size() ; ++i ) + _attributes.push_back( other->_attributes[i] ); + } + + void JsonObject::clear () + { + _stackeds.clear(); + _attributes.clear(); + _collections.clear(); + boost::any emptyAny; + _object.swap( emptyAny ); + } + + +// ------------------------------------------------------------------- +// Class : "JsonKey". + + class JsonKey : public JsonObject { + public: + inline JsonKey ( const std::string& ); + virtual std::string getTypeName () const; + virtual JsonKey* clone ( unsigned long ) const; + private: + std::string _key; + }; + + +// ------------------------------------------------------------------- +// Class : "JsonDummy". + + class JsonDummy : public JsonObject { + public: + inline JsonDummy (); + virtual bool isDummy () const; + virtual std::string getTypeName () const; + void setTypeName ( const std::string& name ); + virtual JsonDummy* clone ( unsigned long ) const; + private: + std::string _typename; + }; + + +} // Hurricane namespace. + + +namespace std { + + template<> + struct less { + inline bool operator() ( const Hurricane::JsonObject* lhs, const Hurricane::JsonObject* rhs ) + { return lhs->getTypeName() < rhs->getTypeName(); } + }; + +} // std namespace. + + +namespace Hurricane { + +// ------------------------------------------------------------------- +// Class : "JsonTypes". + + class JsonTypes { + public: + static void initialize (); + static void registerType ( JsonObject* ); + static JsonObject* find ( const std::string& tname ); + private: + JsonTypes (); + ~JsonTypes (); + JsonTypes ( const JsonTypes& ); + void _registerType ( JsonObject* ); + JsonObject* _find ( const std::string& tname ); + private: + static JsonTypes* _jsonTypes; + std::set _jsonObjects; + }; + + +// ------------------------------------------------------------------- +// Class : "HookKey". + + class HookKey { + public: + inline HookKey ( unsigned int id, const std::string& tname ); + inline unsigned int id () const; + inline std::string tname () const; + private: + unsigned int _id; + std::string _tname; + }; + + + inline HookKey::HookKey ( unsigned int id, const std::string& tname ) : _id(id), _tname(tname) { } + inline unsigned int HookKey::id () const { return _id; } + inline std::string HookKey::tname () const { return _tname; } + + inline bool operator< ( const HookKey& lhs, const HookKey& rhs ) + { + if (lhs.id() != rhs.id()) return lhs.id() < rhs.id(); + return lhs.tname() < rhs.tname(); + } + + +// ------------------------------------------------------------------- +// Class : "HookElement". + + class HookElement { + public: + enum Flags { OpenRingStart = (1<<0) + , ClosedRing = (1<<1) + }; + public: + inline HookElement ( Hook*, unsigned long flags=0 ); + inline Hook* hook () const; + inline HookElement* next () const; + inline void setHook ( Hook* ); + inline void setNext ( HookElement* ); + inline unsigned long flags () const; + inline HookElement& setFlags ( unsigned long mask ); + inline HookElement& resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + private: + Hook* _hook; + HookElement* _next; + unsigned long _flags; + }; + + + inline HookElement::HookElement ( Hook* hook, unsigned long flags ) : _hook(hook), _next(NULL), _flags(flags) { } + inline Hook* HookElement::hook () const { return _hook; } + inline HookElement* HookElement::next () const { return _next; } + inline void HookElement::setHook ( Hook* hook ) { _hook = hook; } + inline void HookElement::setNext ( HookElement* element ) { _next = element; } + inline unsigned long HookElement::flags () const { return _flags; } + inline HookElement& HookElement::setFlags ( unsigned long mask ) { _flags |= mask; return *this; } + inline HookElement& HookElement::resetFlags ( unsigned long mask ) { _flags &= ~mask; return *this; } + inline bool HookElement::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + + typedef map HookLut; + + +// ------------------------------------------------------------------- +// Class : "JsonStack". + + class JsonStack { + public: + typedef std::pair Element; + public: + static bool hookFromString ( std::string s, unsigned int& id, std::string& tname ); + public: + inline JsonStack (); + inline size_t size () const; + template inline void push_back ( const std::string&, T ); + inline void pop_back ( size_t count=1 ); + inline int rhas ( const std::string& ) const; + template inline T as ( const std::string& ) const; + template inline T as ( int ) const; + template inline T getEntity ( unsigned int ) const; + void addEntity ( unsigned int jsonId, Entity* ); + void addHookLink ( Hook*, unsigned int jsonId, const std::string& jsonNext ); + Hook* getHook ( unsigned int jsonId, const std::string& tname ) const; + bool checkRings () const; + void buildRings () const; + inline void clearHookLinks (); + void print ( std::ostream& ) const; + inline JsonStack* setFlags ( unsigned long mask ); + inline JsonStack* resetFlags ( unsigned long mask ); + inline bool issetFlags ( unsigned long mask ) const; + inline const Element& operator[] ( int index ) const; + private: + unsigned long _flags; + vector _stack; + std::map _entities; + HookLut _hooks; + }; + + + inline JsonStack::JsonStack () + : _flags(0), _stack(), _entities(), _hooks() + { } + + template inline void JsonStack::push_back ( const std::string& key, T t ) + { + ltrace(51) << "JsonStack::push_back() key:" << key << " value:" << t + << " (" << demangle(typeid(T)) << ")." << endl; + _stack.push_back(std::make_pair(key,boost::any(t))); + } + + inline void JsonStack::pop_back ( size_t count ) + { + while (count--) { + if (_stack.empty()) { + std::cerr << "[ERROR] JsonStack::pop_back(): Stack is empty, but " + << (count+1) << " elements remains to pop." << std::endl; + break; + } + ltrace(51) << "| _stack.pop_back() " << _stack.back().first << endl; + _stack.pop_back(); + } + } + + inline const JsonStack::Element& JsonStack::operator[] ( int index ) const + { + if (index < 0) return _stack[_stack.size()+index]; + return _stack[index]; + } + + inline int JsonStack::rhas ( const std::string& key ) const + { + if (_stack.empty()) return 0; + + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" found at index:" + << (i-(int)_stack.size()) << " (i:" << i << ") " + << "(" << demangle(_stack[i].second.type().name()) << ")." + << endl; + return i-(int)_stack.size(); + } + if (i == 0) break; + --i; + } while ( true ); + + ltrace(51) << "JsonStack::rhas(): key \"" << key << "\" not found (returning index: 0)." << endl; + return 0; + } + + template inline T JsonStack::as ( const std::string& key ) const + { + if (not _stack.empty()) { + int i = _stack.size()-1; + do { + if (_stack[i].first == key) { + ltrace(51) << "JsonStack::as() k:" << key + << " value:" << demangle(_stack[i].second.type().name()) << std::endl; + return boost::any_cast( _stack[i].second ); + } + if (i == 0) break; + --i; + } while ( true ); + + std::cerr << "[ERROR] JsonStack::as(key): No element with key \"" + << key << "\" in stack." << std::endl; + } else { + std::cerr << "[ERROR] JsonStack::as(key): Stack is empty while searching for key \"" + << key << "\"." << std::endl; + } + + return T(); + } + + template inline T JsonStack::as ( int index ) const + { + size_t i = (index >= 0) ? index : (_stack.size()+index); + return boost::any_cast( _stack[i].second ); + } + + template inline T JsonStack::getEntity ( unsigned int id ) const + { + std::map::const_iterator it = _entities.find(id); + if (it == _entities.end()) return NULL; + return dynamic_cast((*it).second); + } + + inline void JsonStack::clearHookLinks () { _hooks.clear(); } + inline size_t JsonStack::size () const { return _stack.size(); } + inline JsonStack* JsonStack::setFlags ( unsigned long mask ) { _flags |= mask; return this; } + inline JsonStack* JsonStack::resetFlags ( unsigned long mask ) { _flags &= ~mask; return this; } + inline bool JsonStack::issetFlags ( unsigned long mask ) const { return _flags & mask; } + + + template + T JsonObject::get ( JsonStack& stack, const std::string& key ) const + { + int index = stack.rhas(key); + if (index == 0) return T();; + if (stack[index].second.type() == typeid(void*)) return T(); + + return stack.as( index ); + } + + template inline void JsonObject::update ( JsonStack& stack, T hobject ) + { + stack.pop_back( _attributes.size() ); + stack.push_back( getStackName(), hobject ); + setObject( hobject ); + } + + +// ------------------------------------------------------------------- +// Function : Json Parsers. + + Cell* jsonCellParse ( std::string filename ); + Cell* jsonBlobParse ( std::string filename ); + + +} // Hurricane namespace. + +#endif // HURRICANE_JSON_READER_H diff --git a/hurricane/src/hurricane/hurricane/JsonWriter.h b/hurricane/src/hurricane/hurricane/JsonWriter.h new file mode 100644 index 00000000..93304d27 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/JsonWriter.h @@ -0,0 +1,207 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/JsonWriter.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_SLOT_H +#error "JsonWriter.h must be included through Commons.h" +#endif + +#ifndef HURRICANE_JSON_WRITER_H +#define HURRICANE_JSON_WRITER_H + +#include +#include + +namespace rapidjson { + class FileWriteStream; +} + +//namespace Hurricane { + + +// ------------------------------------------------------------------- +// Class : "JsonWriter". + + class JsonWriter { + public: + enum Mode { UsePlugReference = (1<<0) + , DesignBlobMode = (1<<1) + , CellMode = (1<<2) + , RegisterMode = (1<<3) + }; + public: + JsonWriter ( std::string fileName ); + ~JsonWriter (); + void key ( const char* ); + void key ( std::string ); + void startObject (); + void startArray (); + void endObject (); + void endArray (); + void write (); + void write ( const char* ); + void write ( std::string ); + void write ( const std::string* ); + void write ( bool ); + void write ( const bool* ); + void write ( int ); + void write ( const int* ); + void write ( long ); + void write ( const long* ); + void write ( unsigned int ); + void write ( const unsigned int* ); + void write ( unsigned long ); + void write ( const unsigned long* ); + void close (); + JsonWriter* setFlags ( unsigned long mask ); + JsonWriter* resetFlags ( unsigned long mask ); + bool issetFlags ( unsigned long mask ) const; + unsigned long getFlags () const; + private: + JsonWriter ( const JsonWriter& ); + JsonWriter& operator= ( const JsonWriter& ) const; + private: + unsigned long _flags; + size_t _bufferSize; + char* _buffer; + FILE* _file; + rapidjson::FileWriteStream* _stream; + void* _writer; + }; + + +//} // Hurricane namespace. + + +// All jsonWrite() overload are put in the top level namespace, +// in order to facilitate additions from other tools. + +inline void jsonWrite ( JsonWriter* w ) { w->write( ); } +inline void jsonWrite ( JsonWriter* w, const char* s ) { w->write(s); } +inline void jsonWrite ( JsonWriter* w, const std::string* s ) { w->write(s); } +inline void jsonWrite ( JsonWriter* w, std::string s ) { w->write(s); } +inline void jsonWrite ( JsonWriter* w, const bool* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, bool v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const int* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, int v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const long* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, long v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const unsigned int* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, unsigned int v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, const unsigned long* v ) { w->write(v); } +inline void jsonWrite ( JsonWriter* w, unsigned long v ) { w->write(v); } + + +//template +//inline void jsonWrite ( JsonWriter* w, const std::string& key, const Type value ) +//{ w->key( key ); w->write( getString(value).c_str() ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const bool* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, bool value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const int* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, int value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const long* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, long value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const unsigned int* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, unsigned int value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const unsigned long* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, unsigned long value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const char* value ) +{ w->key( key ); w->write( value ); } + + +inline void jsonWrite ( JsonWriter* w, const std::string& key, const std::string& value ) +{ w->key( key ); w->write( value ); } + + +template +inline void jsonWrite ( JsonWriter* w, const C* object ) +{ + if (Hurricane::inltrace(50)) + std::cerr << Hurricane::tab + << "jsonWrite<" << Hurricane::demangle(typeid(C).name()) << "*>(w,object)" << std::endl; + Hurricane::ltracein(50); + + if (object) object->toJson( w ); + else jsonWrite(w); + + Hurricane::ltraceout(50); +} + + +template +inline void jsonWrite ( JsonWriter* w, const std::string& key, const C* object ) +{ + if (Hurricane::inltrace(50)) + std::cerr << Hurricane::tab + << "jsonWrite<" << Hurricane::demangle(typeid(C).name()) << "*>(w,key,object)" + << " key:\"" << key << "\"" << std::endl; + Hurricane::ltracein(50); + + w->key( key ); + if (object) object->toJson( w ); + else jsonWrite(w); + + Hurricane::ltraceout(50); +} + + +#endif // HURRICANE_JSON_WRITER_H diff --git a/hurricane/src/hurricane/hurricane/Layer.h b/hurricane/src/hurricane/hurricane/Layer.h index a32b7372..3d4968c3 100644 --- a/hurricane/src/hurricane/hurricane/Layer.h +++ b/hurricane/src/hurricane/hurricane/Layer.h @@ -95,6 +95,7 @@ namespace Hurricane { inline void _setExtractMask ( const Mask& extractMask ); inline void _setNextOfTechnologyLayerMap ( Layer* layer ); virtual void _onDbuChange ( float scale ); + static const Name& _sgetName ( const Layer* ); private: // Internal: Attributes diff --git a/hurricane/src/hurricane/hurricane/Library.h b/hurricane/src/hurricane/hurricane/Library.h index dbfa24f6..f36ee18a 100644 --- a/hurricane/src/hurricane/hurricane/Library.h +++ b/hurricane/src/hurricane/hurricane/Library.h @@ -95,6 +95,7 @@ class Library : public DBo { public: DataBase* getDataBase() const {return _dataBase;}; public: Library* getLibrary() const {return _library;}; public: const Name& getName() const {return _name;}; + public: string getHierarchicalName () const; public: Library* getLibrary(const Name& name) const {return _libraryMap.getElement(name);}; public: Libraries getLibraries() const {return _libraryMap.getElements();}; public: Cell* getCell(const Name& name) const {return _cellMap.getElement(name);}; @@ -115,6 +116,7 @@ class Library : public DBo { public: virtual string _getTypeName() const {return _TName("Library");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; + public: virtual void _toJson( JsonWriter* ) const; public: LibraryMap& _getLibraryMap() {return _libraryMap;}; public: CellMap& _getCellMap() {return _cellMap;}; public: Library* _getNextOfLibraryLibraryMap() const {return _nextOfLibraryLibraryMap;}; @@ -124,6 +126,16 @@ class Library : public DBo { }; +class JsonLibrary : public JsonDBo { +// ******************************* + + public: JsonLibrary(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonLibrary* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Name.h b/hurricane/src/hurricane/hurricane/Name.h index 0d7452f1..6dcbe0ed 100644 --- a/hurricane/src/hurricane/hurricane/Name.h +++ b/hurricane/src/hurricane/hurricane/Name.h @@ -95,6 +95,12 @@ class Name { INSPECTOR_PV_SUPPORT(Hurricane::Name); +inline void jsonWrite ( JsonWriter* w, Hurricane::Name name ) +{ w->write( getString(name).c_str() ); } + +inline void jsonWrite ( JsonWriter* w, const std::string& key, Hurricane::Name name ) +{ w->key( key ); w->write( getString(name).c_str() ); } + #endif // HURRICANE_NAME diff --git a/hurricane/src/hurricane/hurricane/Net.h b/hurricane/src/hurricane/hurricane/Net.h index 195b3302..587e8ffc 100644 --- a/hurricane/src/hurricane/hurricane/Net.h +++ b/hurricane/src/hurricane/hurricane/Net.h @@ -41,7 +41,6 @@ namespace Hurricane { - // **************************************************************************************************** // Net declaration // **************************************************************************************************** @@ -65,6 +64,7 @@ class Net : public Entity { public: Type(const Code& code = UNDEFINED); public: Type(const Type& type); + public: Type(string); public: Type& operator=(const Type& type); @@ -101,6 +101,7 @@ class Net : public Entity { public: Direction(const Code& code = UNDEFINED); public: Direction(const Direction& direction); + public: Direction(string); public: Direction& operator =(const Direction& direction); public: Direction& operator|=(const Direction& direction); @@ -241,9 +242,11 @@ class Net : public Entity { // ****** protected: virtual void _postCreate(); - protected: virtual void _preDestroy(); + public: virtual void _toJson(JsonWriter*) const; + public: virtual void _toJsonSignature(JsonWriter*) const; + public: virtual void _toJsonCollections(JsonWriter*) const; public: virtual string _getTypeName() const {return _TName("Net");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -256,6 +259,22 @@ class Net : public Entity { }; +class JsonNet : public JsonEntity { +// ******************************** + + public: JsonNet(unsigned long flags); + public: virtual ~JsonNet(); + public: virtual string getTypeName() const; + public: virtual JsonNet* clone(unsigned long) const; + public: virtual void toData(JsonStack&); + +// Attributes +// ********** + + protected: bool _autoMaterialize; + protected: Net* _net; + protected: JsonStack* _stack; +}; } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/NetAlias.h b/hurricane/src/hurricane/hurricane/NetAlias.h index 655239d8..161b241c 100644 --- a/hurricane/src/hurricane/hurricane/NetAlias.h +++ b/hurricane/src/hurricane/hurricane/NetAlias.h @@ -60,6 +60,7 @@ namespace Hurricane { void attach ( NetAliasHook* ); void detach (); void detachAll (); + inline void toJson ( JsonWriter* ) const; virtual std::string _getString () const = 0; virtual Record* _getRecord () const; public: @@ -187,5 +188,7 @@ namespace Hurricane { INSPECTOR_P_SUPPORT(Hurricane::NetAliasHook); INSPECTOR_P_SUPPORT(Hurricane::NetMainName); INSPECTOR_P_SUPPORT(Hurricane::NetAliasName); + +inline void jsonWrite ( JsonWriter* w, const Hurricane::NetAliasHook* alias ) { jsonWrite(w,alias->getName()); } #endif // HURRICANE_NET_ALIAS_H diff --git a/hurricane/src/hurricane/hurricane/Occurrence.h b/hurricane/src/hurricane/hurricane/Occurrence.h index 0a477269..bcb67a2a 100644 --- a/hurricane/src/hurricane/hurricane/Occurrence.h +++ b/hurricane/src/hurricane/hurricane/Occurrence.h @@ -32,9 +32,8 @@ class Quark; class BasicLayer; - // **************************************************************************************************** -// Occurente declaration +// Occurrence declaration // **************************************************************************************************** class Occurrence { @@ -98,6 +97,7 @@ class Occurrence { public: string _getTypeName() const { return _TName("Occurrence"); }; public: string _getString() const; public: string getCompactString() const; + public: void toJson(JsonWriter*) const; public: Record* _getRecord() const; public: SharedPath* _getSharedPath() const {return _sharedPath;}; public: Quark* _getQuark() const; @@ -105,6 +105,19 @@ class Occurrence { }; +// **************************************************************************************************** +// JsonOccurrence declaration +// **************************************************************************************************** + + +class JsonOccurrence : public JsonObject { +// ********************************** + + public: JsonOccurrence(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonOccurrence* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Pad.h b/hurricane/src/hurricane/hurricane/Pad.h index 0a72e0f5..2350e977 100644 --- a/hurricane/src/hurricane/hurricane/Pad.h +++ b/hurricane/src/hurricane/hurricane/Pad.h @@ -73,6 +73,8 @@ class Pad : public Component { // Others // ****** + public: virtual void _toJson(JsonWriter*) const; + public: static JsonObject* getJsonObject(unsigned long flags); public: virtual string _getTypeName() const {return _TName("Pad");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -80,6 +82,15 @@ class Pad : public Component { }; +class JsonPad : public JsonComponent { +// *********************************** + + public: JsonPad(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonPad* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Path.h b/hurricane/src/hurricane/hurricane/Path.h index bd5d4fc6..231c864e 100644 --- a/hurricane/src/hurricane/hurricane/Path.h +++ b/hurricane/src/hurricane/hurricane/Path.h @@ -98,6 +98,7 @@ class Path { // ****** public: string getCompactString() const; + public: string getJsonString(unsigned long flags) const; public: string _getTypeName() const { return _TName("Occurrence"); }; public: string _getString() const; public: Record* _getRecord() const; diff --git a/hurricane/src/hurricane/hurricane/Plug.h b/hurricane/src/hurricane/hurricane/Plug.h index 0fac5488..245d0399 100644 --- a/hurricane/src/hurricane/hurricane/Plug.h +++ b/hurricane/src/hurricane/hurricane/Plug.h @@ -103,6 +103,7 @@ class Plug : public Component { protected: virtual void _preDestroy(); public: virtual string getName() const; + public: virtual void _toJson(JsonWriter*) const; public: virtual string _getTypeName() const {return _TName("Plug");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -114,6 +115,25 @@ class Plug : public Component { }; +class JsonPlug : public JsonComponent { +// ************************************ + + public: JsonPlug(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonPlug* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + + +class JsonPlugRef : public JsonObject { +// ************************************ + + public: JsonPlugRef(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonPlugRef* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Point.h b/hurricane/src/hurricane/hurricane/Point.h index 72e8f532..caceb531 100644 --- a/hurricane/src/hurricane/hurricane/Point.h +++ b/hurricane/src/hurricane/hurricane/Point.h @@ -25,7 +25,6 @@ namespace Hurricane { - // **************************************************************************************************** // Point declaration // **************************************************************************************************** @@ -83,14 +82,23 @@ class Point { public: string _getTypeName() const { return _TName("Point"); }; public: string _getString() const; public: Record* _getRecord() const; + public: void toJson(JsonWriter*) const; }; +class JsonPoint : public JsonObject { +// ********************************** + + public: JsonPoint(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonPoint* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. - INSPECTOR_PV_SUPPORT(Hurricane::Point); diff --git a/hurricane/src/hurricane/hurricane/RoutingPad.h b/hurricane/src/hurricane/hurricane/RoutingPad.h index 9c54bc32..bf53293a 100644 --- a/hurricane/src/hurricane/hurricane/RoutingPad.h +++ b/hurricane/src/hurricane/hurricane/RoutingPad.h @@ -1,7 +1,6 @@ - // -*- C++ -*- // -// Copyright (c) BULL S.A. 2000-2013, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved // // This file is part of Hurricane. // @@ -19,10 +18,6 @@ // License along with Hurricane. If not, see // . // -// =================================================================== -// -// $Id$ -// // +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | @@ -47,6 +42,9 @@ namespace Hurricane { class Segment; +// ------------------------------------------------------------------- +// Class : "RoutingPad". + class RoutingPad : public Component { public: typedef Component Inherit; @@ -85,6 +83,7 @@ namespace Hurricane { // Miscellaeous. Component* _getEntityAsComponent () const; Segment* _getEntityAsSegment () const; + virtual void _toJson ( JsonWriter* ) const; virtual std::string _getTypeName () const {return _TName("RoutingPad");}; virtual std::string _getString () const; virtual Record* _getRecord () const; @@ -99,6 +98,17 @@ namespace Hurricane { }; +// ------------------------------------------------------------------- +// Class : "JsonRoutingPad". + + class JsonRoutingPad : public JsonComponent { + public: + JsonRoutingPad ( unsigned long flags ); + virtual std::string getTypeName () const; + virtual JsonRoutingPad* clone ( unsigned long flags ) const; + virtual void toData ( JsonStack& ); + }; + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Segment.h b/hurricane/src/hurricane/hurricane/Segment.h index 9632fa3c..78e7ab35 100644 --- a/hurricane/src/hurricane/hurricane/Segment.h +++ b/hurricane/src/hurricane/hurricane/Segment.h @@ -26,7 +26,6 @@ namespace Hurricane { - // **************************************************************************************************** // Segment declaration // **************************************************************************************************** @@ -52,8 +51,9 @@ class Segment : public Component { public: virtual bool isMaster() const {return false;}; - public: virtual string _getTypeName() const { return _TName("Segment::SourceHook"); }; + public: virtual string _getTypeName() const { return "Segment::SourceHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; public: class TargetHook : public Hook { @@ -69,8 +69,9 @@ class Segment : public Component { public: virtual bool isMaster() const {return false;}; - public: virtual string _getTypeName() const { return _TName("Segment::TargetHook"); }; + public: virtual string _getTypeName() const { return "Segment::TargetHook"; }; public: virtual string _getString() const; + public: static Hook* _compToHook(Component*); }; // Attributes @@ -127,12 +128,24 @@ class Segment : public Component { protected: virtual void _preDestroy(); + public: virtual void _toJson(JsonWriter*) const; public: virtual string _getString() const; public: virtual Record* _getRecord() const; }; +// **************************************************************************************************** +// JsonSegment declaration +// **************************************************************************************************** + +class JsonSegment : public JsonComponent { +// *************************************** + + public: JsonSegment(unsigned long flags); +}; + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/SharedPath.h b/hurricane/src/hurricane/hurricane/SharedPath.h index 3f2619a2..20ff5d1f 100644 --- a/hurricane/src/hurricane/hurricane/SharedPath.h +++ b/hurricane/src/hurricane/hurricane/SharedPath.h @@ -97,6 +97,7 @@ class SharedPath { public: SharedPath* getHeadSharedPath() const; public: Instance* getTailInstance() const; public: string getName() const; + public: string getJsonString(unsigned long flags) const; public: Cell* getOwnerCell() const; public: Cell* getMasterCell() const; public: Instances getInstances() const; diff --git a/hurricane/src/hurricane/hurricane/Signature.h b/hurricane/src/hurricane/hurricane/Signature.h new file mode 100644 index 00000000..1ea2d777 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/Signature.h @@ -0,0 +1,149 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Authors : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/Signature.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_SIGNATURE_H +#define HURRICANE_SIGNATURE_H + +#include "hurricane/DbU.h" + + +namespace Hurricane { + + class Layer; + + +// ------------------------------------------------------------------- +// Class : "Signature". + + class Signature { + public: + enum Type { TypeContact = 1 + , TypeVertical = 2 + , TypeHorizontal = 3 + , TypePad = 4 + , TypePlug = 5 + , TypeNet = 6 + , TypeInstance = 7 + }; + enum DimContacts { ContactDx = 0 + , ContactDy = 1 + , ContactWidth = 2 + , ContactHeight = 3 + }; + enum DimVertical { VerticalWidth = 0 + , VerticalX = 1 + , VerticalDySource = 2 + , VerticalDyTarget = 3 + }; + enum DimHorizontal { HorizontalWidth = 0 + , HorizontalY = 1 + , HorizontalDxSource = 2 + , HorizontalDxTarget = 3 + }; + enum DimPad { PadXMin = 0 + , PadYMin = 1 + , PadXMax = 2 + , PadYMax = 3 + }; + public: + inline Signature (); + inline Signature ( const Signature& ); + inline Type getType () const; + inline std::string getName () const; + inline std::string getMasterNet () const; + inline const Layer* getLayer () const; + inline DbU::Unit getDim ( size_t index ) const; + inline void setType ( Type ); + inline void setName ( const std::string& ); + inline void setMasterNet ( const std::string& ); + void setLayer ( const std::string& ); + inline void setDim ( size_t index, DbU::Unit ); + private: + // Attributes. + Type _type; + std::string _name; // For Cell, Instance & Net. + std::string _masterNet; // For Plug. + const Layer* _layer; // For Components (save Plug). + DbU::Unit _dims[4]; // Dimensions. + }; + + + inline Signature::Signature () + : _type () + , _name () + , _masterNet() + , _layer (NULL) + { + for ( size_t i=0 ; i<4 ; ++i ) _dims[i] = 0; + } + + + inline Signature::Signature ( const Signature& other ) + : _type (other._type ) + , _name (other._name ) + , _masterNet(other._masterNet) + , _layer (other._layer ) + { + for ( size_t i=0 ; i<4 ; ++i ) _dims[i] = other._dims[i]; + } + + + inline Signature::Type Signature::getType () const { return _type; } + inline std::string Signature::getName () const { return _name; } + inline std::string Signature::getMasterNet () const { return _masterNet; } + inline const Layer* Signature::getLayer () const { return _layer; } + inline DbU::Unit Signature::getDim ( size_t index ) const { return _dims[index]; } + inline void Signature::setType ( Signature::Type type ) { _type=type; } + inline void Signature::setName ( const std::string& name ) { _name=name; } + inline void Signature::setMasterNet ( const std::string& masterNet ) { _masterNet=masterNet; } + inline void Signature::setDim ( size_t index, DbU::Unit u ) { _dims[index]=u; } + + +// ------------------------------------------------------------------- +// Class : "Signature". + + class JsonSignature : public JsonObject { + public: + JsonSignature ( unsigned long flags ); + void setSubType ( const std::string& ); + virtual std::string getTypeName () const; + virtual JsonSignature* clone ( unsigned long flags ) const; + virtual void toData ( JsonStack& ); + private: + JsonSignature ( const JsonSignature& ); + JsonSignature& operator= ( const JsonSignature& ) const; + private: + std::string _subTypeName; + }; + +} // End of Hurricane namespace. + +#endif // HURRICANE_SIGNATURE_H diff --git a/hurricane/src/hurricane/hurricane/Tabulation.h b/hurricane/src/hurricane/hurricane/Tabulation.h index b3163116..9202dcb9 100644 --- a/hurricane/src/hurricane/hurricane/Tabulation.h +++ b/hurricane/src/hurricane/hurricane/Tabulation.h @@ -23,7 +23,7 @@ #include "hurricane/Commons.h" #ifndef HURRICANE_SLOT_H -#error "Tabulation.h must be included after Commons.h" +#error "Tabulation.h must be included through Commons.h" #endif namespace Hurricane { diff --git a/hurricane/src/hurricane/hurricane/Transformation.h b/hurricane/src/hurricane/hurricane/Transformation.h index 67c8b5bb..0043fdd9 100644 --- a/hurricane/src/hurricane/hurricane/Transformation.h +++ b/hurricane/src/hurricane/hurricane/Transformation.h @@ -25,7 +25,6 @@ namespace Hurricane { - // **************************************************************************************************** // Transformation declaration // **************************************************************************************************** @@ -45,6 +44,7 @@ class Transformation { public: Orientation(const Code& code = ID); public: Orientation(const Orientation& orientation); + public: Orientation(const string& ); public: Orientation& operator=(const Orientation& orientation); @@ -135,9 +135,18 @@ class Transformation { public: string _getTypeName() const { return _TName("Transformation"); }; public: string _getString() const; public: Record* _getRecord() const; + public: void toJson(JsonWriter*) const; }; +class JsonTransformation : public JsonObject { +// ******************************************* + + public: JsonTransformation(unsigned long); + public: virtual string getTypeName() const; + public: virtual JsonTransformation* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; } // End of Hurricane namespace. @@ -203,7 +212,6 @@ INSPECTOR_PV_SUPPORT(Hurricane::Transformation); INSPECTOR_PV_SUPPORT(Hurricane::Transformation::Orientation); IOSTREAM_POINTER_SUPPORT(Hurricane::Transformation::Orientation::Code); - #endif // HURRICANE_TRANSFORMATION diff --git a/hurricane/src/hurricane/hurricane/Vertical.h b/hurricane/src/hurricane/hurricane/Vertical.h index bb3d6c28..28f98cff 100644 --- a/hurricane/src/hurricane/hurricane/Vertical.h +++ b/hurricane/src/hurricane/hurricane/Vertical.h @@ -105,6 +105,8 @@ class Vertical : public Segment { // Others // ****** + public: virtual void _toJson(JsonWriter*) const; + public: static JsonObject* getJsonObject(unsigned long flags); public: virtual string _getTypeName() const {return _TName("Vertical");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; @@ -112,6 +114,15 @@ class Vertical : public Segment { }; +class JsonVertical : public JsonSegment { +// ************************************** + + public: JsonVertical(unsigned long flags); + public: virtual string getTypeName() const; + public: virtual JsonVertical* clone(unsigned long) const; + public: virtual void toData(JsonStack&); +}; + } // End of Hurricane namespace. diff --git a/hurricane/src/isobar/CMakeLists.txt b/hurricane/src/isobar/CMakeLists.txt index 66ea5835..43ae1e09 100644 --- a/hurricane/src/isobar/CMakeLists.txt +++ b/hurricane/src/isobar/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories( ${HURRICANE_SOURCE_DIR}/src/hurricane ${HURRICANE_SOURCE_DIR}/src/viewer ${HURRICANE_SOURCE_DIR}/src/isobar + ${CONFIGURATION_INCLUDE_DIR} ${PYTHON_INCLUDE_PATH} ) set( pyCpps ProxyProperty.cpp diff --git a/hurricane/src/viewer/CMakeLists.txt b/hurricane/src/viewer/CMakeLists.txt index 344b80eb..067890cd 100644 --- a/hurricane/src/viewer/CMakeLists.txt +++ b/hurricane/src/viewer/CMakeLists.txt @@ -28,6 +28,7 @@ hurricane/viewer/CellViewer.h hurricane/viewer/CellPrinter.h hurricane/viewer/CellImage.h + hurricane/viewer/OpenBlobDialog.h hurricane/viewer/RecordModel.h hurricane/viewer/InspectorWidget.h hurricane/viewer/SelectionPopupModel.h @@ -96,6 +97,7 @@ CellViewer.cpp CellPrinter.cpp CellImage.cpp + OpenBlobDialog.cpp RecordModel.cpp InspectorWidget.cpp SelectionPopupModel.cpp diff --git a/hurricane/src/viewer/CellPrinter.cpp b/hurricane/src/viewer/CellPrinter.cpp index 53ef93a3..40acd879 100644 --- a/hurricane/src/viewer/CellPrinter.cpp +++ b/hurricane/src/viewer/CellPrinter.cpp @@ -294,8 +294,8 @@ namespace Hurricane { _paperWidth = _printer->width (); _paperHeight = _printer->height (); - _drawingWidth = _paperWidth - (frameMargin()<<1); - _drawingHeight = _paperHeight - (frameMargin()<<1); + _drawingWidth = _paperWidth /4 - (frameMargin()<<1); + _drawingHeight = _paperHeight/4 - (frameMargin()<<1); _xpaper = (imageOnly) ? 0 : frameMargin(); _ypaper = (imageOnly) ? 0 : frameMargin(); diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index f7dff57d..cdfe7f43 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -32,8 +32,11 @@ #include "vlsisapd/utilities/Path.h" #include "vlsisapd/configuration/Configuration.h" +#include "hurricane/DebugSession.h" #include "hurricane/DataBase.h" +#include "hurricane/Library.h" #include "hurricane/Cell.h" +#include "hurricane/DesignBlob.h" //#include "MapView.h" #include "hurricane/isobar/PyCell.h" #include "hurricane/viewer/Script.h" @@ -46,6 +49,7 @@ #include "hurricane/viewer/ScriptWidget.h" #include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/viewer/GotoWidget.h" +#include "hurricane/viewer/OpenBlobDialog.h" #include "hurricane/viewer/SelectCommand.h" #include "hurricane/viewer/PyCellViewer.h" @@ -393,6 +397,22 @@ namespace Hurricane { action->setVisible( false ); addToMenu( "file.========" ); + action = addToMenu( "file.openDesignBlob" + , tr("&Open Design Blob") + , tr("Reload (restore) the whole Hurricane DataBase state") + , QKeySequence() + , QIcon(":/images/stock_open.png") + ); + connect( action, SIGNAL(triggered()), this, SLOT(openDesignBlob()) ); + action = addToMenu( "file.saveDesignBlob" + , tr("&Save Design Blob") + , tr("Save (dump) the whole Hurricane DataBase state") + , QKeySequence() + , QIcon(":/images/stock_save.png") + ); + connect( action, SIGNAL(triggered()), this, SLOT(saveDesignBlob()) ); + addToMenu( "file.========" ); + action = addToMenu( "file.importCell" , tr("&Import Cell") , tr("Import (convert) a new Cell") @@ -702,6 +722,36 @@ namespace Hurricane { } + void CellViewer::openDesignBlob () + { + QString blobName; + if (OpenBlobDialog::runDialog(this,blobName)) { + string fileName = blobName.toStdString() + ".blob"; + DebugSession::open( 50 ); + Cell* topCell = jsonBlobParse( fileName ); + DebugSession::close(); + + setCell ( topCell ); + } + } + + + void CellViewer::saveDesignBlob () + { + Cell* cell = getCell(); + if (not cell) return; + + string blobName = getString(cell->getName()) + ".blob.json"; + DesignBlob blob ( cell ); + + DebugSession::open( 50 ); + JsonWriter writer ( blobName ); + writer.setFlags( JsonWriter::DesignBlobMode ); + jsonWrite( &writer, &blob ); + DebugSession::close(); + } + + void CellViewer::select ( Occurrence& occurrence ) { if ( _cellWidget ) _cellWidget->select ( occurrence ); } diff --git a/hurricane/src/viewer/CellWidget.cpp b/hurricane/src/viewer/CellWidget.cpp index 4a4a99d9..a7a49d32 100644 --- a/hurricane/src/viewer/CellWidget.cpp +++ b/hurricane/src/viewer/CellWidget.cpp @@ -1042,7 +1042,7 @@ namespace Hurricane { // Class : "Hurricane::CellWidget". - int CellWidget::_initialSide = 400; + int CellWidget::_initialSide = 250; CellWidget::CellWidget ( QWidget* parent ) diff --git a/hurricane/src/viewer/OpenBlobDialog.cpp b/hurricane/src/viewer/OpenBlobDialog.cpp new file mode 100644 index 00000000..eb87dd89 --- /dev/null +++ b/hurricane/src/viewer/OpenBlobDialog.cpp @@ -0,0 +1,97 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./OpenBlobDialog.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hurricane/Warning.h" +#include "hurricane/viewer/Graphics.h" +#include "hurricane/viewer/OpenBlobDialog.h" + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "OpenBlobDialog". + + + OpenBlobDialog::OpenBlobDialog ( QWidget* parent ) + : QDialog (parent) + , _lineEdit(NULL) + { + setWindowTitle( tr("Open Design Blob") ); + + QLabel* label = new QLabel (); + label->setText( tr("Enter the Blob name (without extention \".blob.json\")") ); + label->setFont( Graphics::getNormalFont(true) ); + + _lineEdit = new QLineEdit (); + _lineEdit->setMinimumWidth( 400 ); + + QPushButton* okButton = new QPushButton (); + okButton->setText ( "OK" ); + okButton->setDefault( true ); + + QPushButton* cancelButton = new QPushButton (); + cancelButton->setText( "Cancel" ); + + QHBoxLayout* hLayout1 = new QHBoxLayout (); + hLayout1->addStretch(); + hLayout1->addWidget ( okButton ); + hLayout1->addStretch(); + hLayout1->addWidget ( cancelButton ); + hLayout1->addStretch(); + + QVBoxLayout* vLayout = new QVBoxLayout (); + vLayout->setSizeConstraint ( QLayout::SetFixedSize ); + vLayout->addWidget( label ); + vLayout->addWidget( _lineEdit ); + vLayout->addLayout( hLayout1 ); + + setLayout ( vLayout ); + + connect ( okButton, SIGNAL(clicked()), this, SLOT(accept()) ); + connect ( cancelButton, SIGNAL(clicked()), this, SLOT(reject()) ); + } + + + const QString OpenBlobDialog::getBlobName () const + { return _lineEdit->text(); } + + + bool OpenBlobDialog::runDialog ( QWidget* parent, QString& name ) + { + OpenBlobDialog* dialog = new OpenBlobDialog ( parent ); + bool dialogResult = (dialog->exec() == Accepted); + + name = dialog->getBlobName(); + + delete dialog; + + return dialogResult; + } + + +} // Hurricane namespace. diff --git a/hurricane/src/viewer/hurricane/viewer/CellViewer.h b/hurricane/src/viewer/hurricane/viewer/CellViewer.h index 15705490..0bb9ce08 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/CellViewer.h @@ -136,6 +136,8 @@ namespace Hurricane { void setShowSelection ( bool ); void setState ( shared_ptr& ); void openHistoryCell (); + void openDesignBlob (); + void saveDesignBlob (); void printDisplay (); void print ( QPrinter* ); void imageDisplay (); diff --git a/hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h b/hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h new file mode 100644 index 00000000..b895d4ce --- /dev/null +++ b/hurricane/src/viewer/hurricane/viewer/OpenBlobDialog.h @@ -0,0 +1,42 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/viewer/OpenBlobDialog.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_OPEN_BLOB_DIALOG_H +#define HURRICANE_OPEN_BLOB_DIALOG_H + +#include + +class QLineEdit; + + +namespace Hurricane { + + + class OpenBlobDialog : public QDialog { + Q_OBJECT; + public: + static bool runDialog ( QWidget* parent, QString& name ); + const QString getBlobName () const; + protected: + OpenBlobDialog ( QWidget* parent=NULL ); + protected: + QLineEdit* _lineEdit; + }; + + +} // Hurricane namespace. + +#endif // HURRICANE_OPEN_BLOB_DIALOG_H diff --git a/unicorn/src/ExportCellDialog.cpp b/unicorn/src/ExportCellDialog.cpp index caefb8cf..0073c010 100644 --- a/unicorn/src/ExportCellDialog.cpp +++ b/unicorn/src/ExportCellDialog.cpp @@ -78,6 +78,7 @@ namespace Unicorn { formatLabel->setFont ( Graphics::getNormalFont(true) ); hLayout2->addWidget ( formatLabel ); + _formatComboBox->addItem ( tr("JSON (experimental)") , Json ); _formatComboBox->addItem ( tr("Alliance compliant DEF"), AllianceDef ); _formatComboBox->addItem ( tr("ASCII/GDSII (AGDS)") , AsciiGds ); hLayout2->addWidget ( _formatComboBox ); diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index ccdb0c75..08c5e9bd 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -17,6 +17,7 @@ #include #include #include +#include "hurricane/DebugSession.h" #include "hurricane/Warning.h" #include "hurricane/viewer/Script.h" #include "hurricane/viewer/CellViewer.h" @@ -45,8 +46,10 @@ namespace Unicorn { using Hurricane::dbo_ptr; + using Hurricane::DebugSession; using Hurricane::Warning; using Hurricane::PyCellViewer_Link; + using Hurricane::jsonCellParse; using CRL::System; using CRL::Catalog; using CRL::AllianceFramework; @@ -89,6 +92,7 @@ namespace Unicorn { _runUnicornInit(); _importCell.setDialog( _importDialog ); + _importCell.addImporter( "JSON (experimental)" , std::bind( &jsonCellParse , placeholders::_1 ) ); _importCell.addImporter( "BLIF (Yosys/ABC)" , std::bind( &Blif::load , placeholders::_1 ) ); _importCell.addImporter( "ACM/SIGDA (aka MCNC, .bench)", std::bind( &AcmSigda::load , placeholders::_1 ) ); _importCell.addImporter( "ISPD'04 (Bookshelf)" , std::bind( &Ispd04::load , placeholders::_1 ) ); @@ -282,8 +286,16 @@ namespace Unicorn { DefExport::drive ( cell, DefExport::WithLEF ); break; case ExportCellDialog::AsciiGds: - GdsDriver gdsDriver ( cell ); - gdsDriver.save( getString(cell->getName())+".agds" ); + { GdsDriver gdsDriver ( cell ); + gdsDriver.save( getString(cell->getName())+".agds" ); + } + break; + case ExportCellDialog::Json: + { DebugSession::open( 50 ); + JsonWriter writer ( cellName.toStdString()+".json" ); + jsonWrite( &writer, cell ); + DebugSession::close(); + } break; } } diff --git a/unicorn/src/unicorn/ExportCellDialog.h b/unicorn/src/unicorn/ExportCellDialog.h index cbc2a44b..652ca747 100644 --- a/unicorn/src/unicorn/ExportCellDialog.h +++ b/unicorn/src/unicorn/ExportCellDialog.h @@ -31,7 +31,7 @@ namespace Unicorn { Q_OBJECT; public: - enum Formats { AllianceDef=1, AsciiGds=2 }; + enum Formats { AllianceDef=1, AsciiGds=2, Json=3 }; public: ExportCellDialog ( QWidget* parent=NULL ); bool runDialog ( QString& name, int& format );