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 | ||
7fd59977 | 54 | //============================================================================ |
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 | } | |
7fd59977 | 101 | } |
102 | ||
e7195ab4 | 103 | Standard_Type* Standard_Type::Register (const char* theSystemName, const char* theName, |
104 | Standard_Size theSize, const Handle(Standard_Type)& theParent) | |
7fd59977 | 105 | { |
69ff08ff | 106 | // Access to registry is protected by mutex; it should not happen often because |
107 | // instances are cached by Standard_Type::Instance() (one per binary module) | |
108 | static Standard_Mutex theMutex; | |
109 | Standard_Mutex::Sentry aSentry (theMutex); | |
7fd59977 | 110 | |
69ff08ff | 111 | // return existing descriptor if already in the registry |
112 | registry_type& aRegistry = GetRegistry(); | |
113 | Standard_Type* aType = 0; | |
114 | if (aRegistry.Find (theSystemName, aType)) | |
115 | return aType; | |
7fd59977 | 116 | |
69ff08ff | 117 | // else create a new descriptor |
118 | aType = new Standard_Type (theSystemName, theName, theSize, theParent); | |
7fd59977 | 119 | |
69ff08ff | 120 | // then add it to registry and return (the reference to the handle stored in the registry) |
a0218ba1 | 121 | aRegistry.Bind (aType->mySystemName, aType); |
7fd59977 | 122 | |
04232180 | 123 | // std::cout << "Registering " << theSystemName << ": " << aRegistry.Extent() << std::endl; |
7fd59977 | 124 | |
69ff08ff | 125 | return aType; |
7fd59977 | 126 | } |
127 | ||
69ff08ff | 128 | Standard_Type::~Standard_Type () |
7fd59977 | 129 | { |
69ff08ff | 130 | // remove descriptor from the registry |
131 | registry_type& aRegistry = GetRegistry(); | |
132 | Standard_ASSERT(aRegistry.UnBind (mySystemName), "Standard_Type::~Standard_Type() cannot find itself in registry",); | |
7fd59977 | 133 | |
04232180 | 134 | // std::cout << "Unregistering " << mySystemName << ": " << aRegistry.Extent() << std::endl; |
a0218ba1 | 135 | Standard::Free (mySystemName); |
795be040 | 136 | Standard::Free (myName); |
7fd59977 | 137 | } |