Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1998-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
b311480e | 14 | |
7fd59977 | 15 | |
69ff08ff | 16 | #include <Standard_Type.hxx> |
17 | #include <Standard_Mutex.hxx> | |
18 | #include <Standard_Assert.hxx> | |
7fd59977 | 19 | |
69ff08ff | 20 | #include <NCollection_DataMap.hxx> |
7fd59977 | 21 | |
f5f4ebd0 | 22 | IMPLEMENT_STANDARD_RTTIEXT(Standard_Type,Standard_Transient) |
23 | ||
7fd59977 | 24 | //============================================================================ |
25 | ||
a0218ba1 RL |
26 | namespace { |
27 | static Standard_CString copy_string (const char* theString) | |
28 | { | |
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 | |
32 | return aResult; | |
33 | } | |
34 | } | |
35 | ||
36 | Standard_Type::Standard_Type (const char* theSystemName, | |
37 | const char* theName, | |
38 | Standard_Size theSize, | |
39 | const Handle(Standard_Type)& theParent) : | |
795be040 | 40 | mySystemName(copy_string (theSystemName)), |
41 | myName(copy_string (theName)), | |
42 | mySize(theSize), | |
43 | myParent(theParent) | |
a0218ba1 RL |
44 | { |
45 | } | |
46 | ||
47 | //============================================================================ | |
48 | ||
69ff08ff | 49 | Standard_Boolean Standard_Type::SubType (const Handle(Standard_Type)& theOther) const |
7fd59977 | 50 | { |
69ff08ff | 51 | return ! theOther.IsNull() && (theOther == this || (! myParent.IsNull() && myParent->SubType (theOther))); |
7fd59977 | 52 | } |
53 | ||
54 | //============================================================================ | |
7fd59977 | 55 | |
69ff08ff | 56 | Standard_Boolean Standard_Type::SubType (const Standard_CString theName) const |
7fd59977 | 57 | { |
42a9dcfc | 58 | return theName != 0 && (IsEqual (myName, theName) || (! myParent.IsNull() && myParent->SubType (theName))); |
7fd59977 | 59 | } |
60 | ||
69ff08ff | 61 | // ------------------------------------------------------------------ |
62 | // Print (me; s: in out OStream) returns OStream; | |
63 | // ------------------------------------------------------------------ | |
64 | void Standard_Type::Print (Standard_OStream& AStream) const | |
7fd59977 | 65 | { |
04232180 | 66 | AStream << std::hex << (Standard_Address)this << " : " << std::dec << myName ; |
7fd59977 | 67 | } |
68 | ||
69 | //============================================================================ | |
69ff08ff | 70 | // Registry of types |
7fd59977 | 71 | //============================================================================ |
7fd59977 | 72 | |
69ff08ff | 73 | namespace { |
74 | // Value-based hasher for plain C string (char*) | |
75 | struct CStringHasher | |
76 | { | |
2b2be3fb | 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) | |
69ff08ff | 82 | { |
2b2be3fb | 83 | return ::HashCode (theKey, theUpperBound); |
69ff08ff | 84 | } |
85 | static bool IsEqual (const Standard_CString& theKey1, const Standard_CString& theKey2) | |
86 | { | |
87 | return ! strcmp (theKey1, theKey2); | |
88 | } | |
89 | }; | |
7fd59977 | 90 | |
69ff08ff | 91 | // Map of string to type |
92 | typedef NCollection_DataMap<Standard_CString, Standard_Type*, CStringHasher> registry_type; | |
7fd59977 | 93 | |
69ff08ff | 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() | |
97 | { | |
98 | static registry_type theRegistry; | |
99 | return theRegistry; | |
100 | } | |
ef779ae0 | 101 | |
102 | // To initialize theRegistry map as soon as possible to be destoryed the latest | |
103 | Handle(Standard_Type) theType = STANDARD_TYPE(Standard_Transient); | |
7fd59977 | 104 | } |
105 | ||
e7195ab4 | 106 | Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName, |
107 | Standard_Size theSize, const Handle(Standard_Type)& theParent) | |
7fd59977 | 108 | { |
69ff08ff | 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); | |
7fd59977 | 113 | |
69ff08ff | 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)) | |
118 | return aType; | |
7fd59977 | 119 | |
69ff08ff | 120 | // else create a new descriptor |
121 | aType = new Standard_Type (theSystemName, theName, theSize, theParent); | |
7fd59977 | 122 | |
69ff08ff | 123 | // then add it to registry and return (the reference to the handle stored in the registry) |
a0218ba1 | 124 | aRegistry.Bind (aType->mySystemName, aType); |
7fd59977 | 125 | |
04232180 | 126 | // std::cout << "Registering " << theSystemName << ": " << aRegistry.Extent() << std::endl; |
7fd59977 | 127 | |
69ff08ff | 128 | return aType; |
7fd59977 | 129 | } |
130 | ||
69ff08ff | 131 | Standard_Type::~Standard_Type () |
7fd59977 | 132 | { |
69ff08ff | 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",); | |
7fd59977 | 136 | |
04232180 | 137 | // std::cout << "Unregistering " << mySystemName << ": " << aRegistry.Extent() << std::endl; |
a0218ba1 | 138 | Standard::Free (mySystemName); |
795be040 | 139 | Standard::Free (myName); |
7fd59977 | 140 | } |