// Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(Interface_UndefinedContent,Standard_Transient) #define Content_TypeField 31 #define Content_LocalField 7 #define Content_LocalRef 1 #define Content_LocalShift 5 #define Content_NumberShift 8 // Cette classe donne les services de base pour definir des entites // Unknown (ceci, a defaut d'un double heritage) : description litterale Interface_UndefinedContent::Interface_UndefinedContent () // Unknown { thenbparams = 0; thenbstr = 0; } // .... Les Parametres .... // Les parametres sont organises comme suit (pas de FileParameter) : // - une liste de descripteurs (tenant sur un entier chacun) en tableau, avec // la localisation (Entity/literal), le type (ParamType), le rang dans la // la liste ad hoc (Entity ou literal) // (5 bits droits pour type; 3 bits pour localisation; restant pouradresse) // - pour les litteraux, une liste de String (tableau) // - pour les Entity, une liste d Entites (EntityList) // L aspect "place memoire" fait preferer des Tableaux a des Sequences, bien // que ces dernieres soient plus simples a gerer // En effet, il faut reserver et etendre si necessaire ... Standard_Integer Interface_UndefinedContent::NbParams () const { return thenbparams; } Standard_Integer Interface_UndefinedContent::NbLiterals () const { return thenbstr; } Standard_Boolean Interface_UndefinedContent::ParamData (const Standard_Integer num, Interface_ParamType& ptype, Handle(Standard_Transient)& ent, Handle(TCollection_HAsciiString)& val) const { if (num < 1 || num > thenbparams) throw Standard_OutOfRange("Interface UndefinedContent : ParamData"); Standard_Integer desc = theparams->Value(num); Standard_Integer local = ((desc >> Content_LocalShift) & Content_LocalField); ptype = Interface_ParamType (desc & Content_TypeField); Standard_Integer adr = desc >> Content_NumberShift; if (local == Content_LocalRef) ent = theentities.Value(adr); else val = thevalues->Value(adr); return (local == Content_LocalRef); } Interface_ParamType Interface_UndefinedContent::ParamType (const Standard_Integer num) const { return Interface_ParamType(theparams->Value(num) & Content_TypeField); } Standard_Boolean Interface_UndefinedContent::IsParamEntity (const Standard_Integer num) const { return ( ((theparams->Value(num) >> Content_LocalShift) & Content_LocalField) == Content_LocalRef); } Handle(Standard_Transient) Interface_UndefinedContent::ParamEntity (const Standard_Integer num) const { Standard_Integer desc = theparams->Value(num); if (((desc >> Content_LocalShift) & Content_LocalField) != Content_LocalRef) throw Interface_InterfaceError("UndefinedContent : Param is not Entity type"); return theentities.Value (desc >> Content_NumberShift); } Handle(TCollection_HAsciiString) Interface_UndefinedContent::ParamValue (const Standard_Integer num) const { Standard_Integer desc = theparams->Value(num); if (((desc >> Content_LocalShift) & Content_LocalField) != 0) throw Interface_InterfaceError("UndefinedContent : Param is not literal"); return thevalues->Value (desc >> Content_NumberShift); } // .... Remplissage des parametres .... void Interface_UndefinedContent::Reservate (const Standard_Integer nb, const Standard_Integer nblit) { // Reservation : Si agrandissement, recopier ancien dans nouveau ... if (nb > thenbparams) { // Reservation en total if (theparams.IsNull()) theparams = new TColStd_HArray1OfInteger (1,nb); else if (nb > theparams->Length()) { Standard_Integer nbnew = 2*thenbparams; // on reserve un peu large if (nbnew < nb) nbnew = nb; Handle(TColStd_HArray1OfInteger) newparams = new TColStd_HArray1OfInteger (1,nbnew); for (Standard_Integer i = 1; i <= thenbparams; i ++) newparams->SetValue(i,theparams->Value(i)); theparams = newparams; } } if (nblit > thenbstr) { // Reservation en Litteraux if (thevalues.IsNull()) thevalues = new Interface_HArray1OfHAsciiString (1,nblit); else if (nblit > thevalues->Length()) { Standard_Integer nbnew = 2*thenbstr; // on reserve un peu large if (nbnew < nblit) nbnew = nblit; Handle(Interface_HArray1OfHAsciiString) newvalues = new Interface_HArray1OfHAsciiString (1,nbnew); for (Standard_Integer i = 1; i <= thenbstr; i ++) newvalues->SetValue(i,thevalues->Value(i)); thevalues = newvalues; } } // Entites : Parametres - Litteraux. En fait, EntityList est dynamique } void Interface_UndefinedContent::AddLiteral (const Interface_ParamType ptype, const Handle(TCollection_HAsciiString)& val) { Reservate (thenbparams+1,thenbstr+1); Standard_Integer desc = Standard_Integer(ptype); thenbstr ++; thenbparams ++; thevalues->SetValue (thenbstr,val); desc += (thenbstr << Content_NumberShift); theparams->SetValue (thenbparams,desc); } void Interface_UndefinedContent::AddEntity (const Interface_ParamType ptype, const Handle(Standard_Transient)& ent) { Reservate (thenbparams+1,0); Standard_Integer desc = Standard_Integer(ptype); theentities.Append (ent); desc += Content_LocalRef << Content_LocalShift; // "C est une Entite" thenbparams ++; // Rang : thenbparams - thenbstr desc += ((thenbparams - thenbstr) << Content_NumberShift); theparams->SetValue (thenbparams,desc); } // .... Edition des parametres .... void Interface_UndefinedContent::RemoveParam (const Standard_Integer num) { Standard_Integer desc = theparams->Value(num); Standard_Integer rang = desc >> Content_NumberShift; Standard_Integer local = ((desc >> Content_LocalShift) & Content_LocalField); Standard_Boolean c1ent = (local == Content_LocalRef); // Supprimer une Entite if (c1ent) theentities.Remove(rang); // Supprimer un Literal else { // thevalues->Remove(rang) mais c est un tableau for (Standard_Integer i = rang+1; i <= thenbstr; i ++) thevalues->SetValue(i-1,thevalues->Value(i)); Handle(TCollection_HAsciiString) nulstr; thevalues->SetValue(thenbstr,nulstr); thenbstr --; } // Supprimer ce parametre de la liste (qui est un tableau) Standard_Integer np; // svv Jan11 2000 : porting on DEC for (np = num+1; np <= thenbparams; np ++) theparams->SetValue(np-1,theparams->Value(np)); theparams->SetValue(thenbparams,0); thenbparams --; // Renumeroter, Entite ou Literal, selon for (np = 1; np <= thenbparams; np ++) { desc = theparams->Value(np); if ( ((desc >> Content_LocalShift) & Content_LocalField) == local && (desc >> Content_NumberShift) > rang) theparams->SetValue(np,desc - (1 << Content_NumberShift)); } } void Interface_UndefinedContent::SetLiteral (const Standard_Integer num, const Interface_ParamType ptype, const Handle(TCollection_HAsciiString)& val) { // On change un parametre. Si deja literal, simple substitution // Si Entite, supprimer l entite et renumeroter les Parametres "Entite" Standard_Integer desc = theparams->Value(num); Standard_Integer rang = desc >> Content_NumberShift; Standard_Integer local = ((desc >> Content_LocalShift) & Content_LocalField); Standard_Boolean c1ent = (local == Content_LocalRef); if (c1ent) { // Entite : la supprimer et renumeroter les Parametres de type "Entity" theentities.Remove(rang); for (Standard_Integer i = 1; i <= thenbparams; i ++) { desc = theparams->Value(i); if ( ((desc >> Content_LocalShift) & Content_LocalField) == Content_LocalRef && (desc >> Content_NumberShift) > rang) theparams->SetValue(i , desc - (1 << Content_NumberShift)); } // Et Preparer arrivee d un Literal supplementaire Reservate (thenbparams,thenbstr+1); thenbstr ++; rang = thenbstr; } // Mettre en place la nouvelle valeur et reconstruire le descripteur du Param thevalues->SetValue(rang,val); desc = Standard_Integer(ptype) + (rang << Content_NumberShift); theparams->SetValue(num,desc); } void Interface_UndefinedContent::SetEntity (const Standard_Integer num, const Interface_ParamType ptype, const Handle(Standard_Transient)& ent) { // On change un Parametre. Si deja Entity, simple substitution // Si Literal, supprimer sa valeur et renumeroter les parametres Litteraux Standard_Integer desc = theparams->Value(num); Standard_Integer rang = desc >> Content_NumberShift; Standard_Integer local = ((desc >> Content_LocalShift) & Content_LocalField); Standard_Boolean c1ent = (local == Content_LocalRef); if (!c1ent) { // Literal : le supprimer et renumeroter les Parametres de type "Entity" // (Remove Literal mais dans un tableau) Standard_Integer i; // svv Jan11 2000 : porting on DEC for (i = rang+1; i <= thenbstr; i ++) thevalues->SetValue(i-1,thevalues->Value(i)); Handle(TCollection_HAsciiString) nulstr; thevalues->SetValue(thenbstr,nulstr); for (i = 1; i <= thenbparams; i ++) { desc = theparams->Value(i); if ( ((desc >> Content_LocalShift) & Content_LocalField) == 0 && (desc >> Content_NumberShift) > rang) theparams->SetValue(i , desc - (1 << Content_NumberShift)); } // Et Preparer arrivee d une Entite supplementaire thenbstr --; rang = thenbparams - thenbstr; // Mettre en place la nouvelle valeur et reconstruire le descripteur du Param theentities.Append(ent); } else theentities.SetValue(rang,ent); desc = Standard_Integer(ptype) + (Content_LocalRef << Content_LocalShift) + (rang << Content_NumberShift); theparams->SetValue(num,desc); } void Interface_UndefinedContent::SetEntity (const Standard_Integer num, const Handle(Standard_Transient)& ent) { // On change l Entite definie par un Parametre, toutes autres choses egales, // A CONDITION que ce soit deja un Parametre de type "Entity" Standard_Integer desc = theparams->Value(num); Standard_Integer rang = desc >> Content_NumberShift; Standard_Integer local = ((desc >> Content_LocalShift) & Content_LocalField); Standard_Boolean c1ent = (local == Content_LocalRef); if (!c1ent) throw Interface_InterfaceError("UndefinedContent : SetEntity"); theentities.SetValue(rang,ent); } Interface_EntityList Interface_UndefinedContent::EntityList () const { return theentities; } // toutes les recopies de UndefinedEntity se ressemblent ... Partie commune void Interface_UndefinedContent::GetFromAnother (const Handle(Interface_UndefinedContent)& other, Interface_CopyTool& TC) { Standard_Integer nb = other->NbParams(); theentities.Clear(); thevalues.Nullify(); theparams.Nullify(); Reservate (nb,other->NbLiterals()); Handle(Standard_Transient) ent; for (Standard_Integer i = 1; i <= nb; i ++) { Interface_ParamType ptype; Handle(TCollection_HAsciiString) val; if (other->ParamData (i, ptype,ent,val)) { ent = TC.Transferred(ent); AddEntity (ptype,ent); } else AddLiteral (ptype,val); } }