1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
16 #include <Standard_Type.hxx>
17 #include <Standard_Mutex.hxx>
18 #include <Standard_Assert.hxx>
20 #include <NCollection_DataMap.hxx>
22 IMPLEMENT_STANDARD_RTTIEXT(Standard_Type,Standard_Transient)
24 //============================================================================
27 static Standard_CString copy_string (const char* theString)
29 size_t aLength = strlen (theString);
30 char* aResult = static_cast<char*> (Standard::Allocate (aLength + 1));
31 strncpy (aResult, theString, aLength + 1); //including null-character
36 Standard_Type::Standard_Type (const char* theSystemName,
38 Standard_Size theSize,
39 const Handle(Standard_Type)& theParent) :
40 mySystemName(copy_string (theSystemName)),
41 myName(copy_string (theName)),
47 //============================================================================
49 Standard_Boolean Standard_Type::SubType (const Handle(Standard_Type)& theOther) const
51 return ! theOther.IsNull() && (theOther == this || (! myParent.IsNull() && myParent->SubType (theOther)));
54 //============================================================================
56 Standard_Boolean Standard_Type::SubType (const Standard_CString theName) const
58 return theName != 0 && (IsEqual (myName, theName) || (! myParent.IsNull() && myParent->SubType (theName)));
61 // ------------------------------------------------------------------
62 // Print (me; s: in out OStream) returns OStream;
63 // ------------------------------------------------------------------
64 void Standard_Type::Print (Standard_OStream& AStream) const
66 AStream << std::hex << (Standard_Address)this << " : " << std::dec << myName ;
69 //============================================================================
71 //============================================================================
74 // Value-based hasher for plain C string (char*)
77 //! Computes a hash code of the given Standard_CString, in the range [1, theUpperBound]
78 //! @param theKey the key which hash code is to be computed
79 //! @param theUpperBound the upper bound of the range a computing hash code must be within
80 //! @return a computed hash code, in the range [1, theUpperBound]
81 static Standard_Integer HashCode (const Standard_CString& theKey, const Standard_Integer theUpperBound)
83 return ::HashCode (theKey, theUpperBound);
85 static bool IsEqual (const Standard_CString& theKey1, const Standard_CString& theKey2)
87 return ! strcmp (theKey1, theKey2);
91 // Map of string to type
92 typedef NCollection_DataMap<Standard_CString, Standard_Type*, CStringHasher> registry_type;
94 // Registry is made static in the function to ensure that it gets
95 // initialized by the time of first access
96 registry_type& GetRegistry()
98 static registry_type theRegistry;
102 // To initialize theRegistry map as soon as possible to be destroyed the latest
103 Handle(Standard_Type) theType = STANDARD_TYPE(Standard_Transient);
106 Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName,
107 Standard_Size theSize, const Handle(Standard_Type)& theParent)
109 // Access to registry is protected by mutex; it should not happen often because
110 // instances are cached by Standard_Type::Instance() (one per binary module)
111 static Standard_Mutex theMutex;
112 Standard_Mutex::Sentry aSentry (theMutex);
114 // return existing descriptor if already in the registry
115 registry_type& aRegistry = GetRegistry();
116 Standard_Type* aType = 0;
117 if (aRegistry.Find (theSystemName, aType))
120 // else create a new descriptor
121 aType = new Standard_Type (theSystemName, theName, theSize, theParent);
123 // then add it to registry and return (the reference to the handle stored in the registry)
124 aRegistry.Bind (aType->mySystemName, aType);
126 // std::cout << "Registering " << theSystemName << ": " << aRegistry.Extent() << std::endl;
131 Standard_Type::~Standard_Type ()
133 // remove descriptor from the registry
134 registry_type& aRegistry = GetRegistry();
135 Standard_ASSERT(aRegistry.UnBind (mySystemName), "Standard_Type::~Standard_Type() cannot find itself in registry",);
137 // std::cout << "Unregistering " << mySystemName << ": " << aRegistry.Extent() << std::endl;
138 Standard::Free (mySystemName);
139 Standard::Free (myName);