0022749: Segfault in HashCode() of Standard_Transient
[occt.git] / src / Standard / Standard_CString.cxx
CommitLineData
7fd59977 1
2// Update JR 12-09-1997 :
3// - three methods of HashCoding of strings : we may keep the value
4// of the hashcode of the string itself. This value is used when
5// resizing of a Map or copying an item from a Map to another Map.
6// - three methods of HashCoding of strings converted to uppercase.
7
8#define _Standard_CString_SourceFile
9
10#define OptJr 1
11#ifdef HAVE_CONFIG_H
12# include <config.h>
13#endif
14
15
16#include <Standard_CString.hxx>
17#include <Standard_Type.hxx>
18#include <Standard_OStream.hxx>
19
20#if OptJr
21# if defined(WORDS_BIGENDIAN)
22static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
23 0xff000000 ,
24 0xffff0000 ,
25 0xffffff00 } ;
26# else
27static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
28 0x000000ff ,
29 0x0000ffff ,
30 0x00ffffff } ;
31# endif
32#endif
33
34#include <Standard_String.hxx>
35#include <string.h>
36
37//============================================================================
38//====
39//============================================================================
40Handle_Standard_Type& Standard_CString_Type_()
41{
42 static Handle_Standard_Type _aType =
43 new Standard_Type("Standard_CString",sizeof(Standard_CString),0,NULL);
44
45 return _aType;
46}
47
48//============================================================================
49//==== ShallowDump : Writes a CString value.
50//============================================================================
51Standard_EXPORT void ShallowDump (const Standard_CString Value, Standard_OStream& s)
52{ s << Value << " Standard_CString " << "\n"; }
53
54//============================================================================
55//==== HashCode of a CString
56//============================================================================
57Standard_Integer HashCode (const Standard_CString Value,
58 const Standard_Integer Upper )
59{
60 Standard_Integer aLen ;
61 //#if OptJr
62 //STRINGLEN( Value , aLen ) ;
63 //#else
64 aLen = (Standard_Integer)strlen(Value);
65 //#endif
66 return HashCode ( HashCodes( Value , aLen ) , Upper ) ;
67}
68
69#if OptJr
70# if defined(WORDS_BIGENDIAN)
71 static Standard_Integer Standard_Mask_String_Left[4] =
72 { 0 , 0x00ffffff , 0x0000ffff , 0x000000ff } ;
73 static Standard_Integer Standard_Mask_String_Right[4] =
74 { 0 , 0xff000000 , 0xffff0000 , 0xffffff00 } ;
75# else
76 static Standard_Integer Standard_Mask_String_Left[4] =
77 { 0 , 0xffffff00 , 0xffff0000 , 0xff000000 } ;
78 static Standard_Integer Standard_Mask_String_Right[4] =
79 { 0 , 0x000000ff , 0x0000ffff , 0x00ffffff } ;
80# endif
81#endif
82
83//============================================================================
84//==== HashCode of a CString
85//============================================================================
86Standard_Integer HashCodes (const Standard_CString Value ,
87 const Standard_Integer Len )
88{
89 Standard_Integer aHashCode = 0 ;
90 Standard_Integer i ;
91#if !OptJr
92 char *charPtr = (char *)Value;
93 Standard_Integer pos = 0,
94 count,
95 *tmphash;
96 char tabchar[20];
97#endif
98
99 if (Value != NULL) {
100
101#if !OptJr
102 i = 0 ;
103 while (i < Len) {
104 for (count = 0,pos = i;count < sizeof(Standard_Integer); count++) {
105 if (pos + count >= Len) tabchar[count] = '\0';
106 else tabchar[count] = charPtr[pos + count];
107 i++;
108 }
109 tmphash = (Standard_Integer *)tabchar;
110 aHashCode = aHashCode ^ *tmphash;
111 }
112 }
113
114#else
115 Standard_Integer *value = (Standard_Integer *)(ptrdiff_t(Value) & ~0x3) ;
116 Standard_Integer len = Len ;
117
118 unsigned int aResidue = (unsigned int)(ptrdiff_t(Value) & 0x3);
119 if (aResidue) {
120 aHashCode = *value & Standard_Mask_String_Left[aResidue] ;
121 value += 1 ;
122 len -= (4 - aResidue);
123 }
124
125 for ( i = 1 ; i <= len >> 2 ; i++ ) {
126 aHashCode = aHashCode ^ value[ i - 1 ] ;
127 }
128 aHashCode = aHashCode ^ ( value[ i - 1 ] &
129 Standard_Mask_String_Right[ len & 3 ] ) ;
130
131 if ( len != Len ) {
132# if defined(WORDS_BIGENDIAN)
133 aHashCode = aHashCode << 8*aResidue |
134 aHashCode >> 8*(4 - aResidue) ;
135# else
136 aHashCode = aHashCode << 8*(4 - aResidue) |
137 aHashCode >> 8*aResidue ;
138# endif
139 }
140
141 }
142#endif
143
144 return aHashCode ;
145}
146
147
148# if defined(WORDS_BIGENDIAN)
149 static Standard_Integer Standard_Mask_Upper_Lower[5] =
150 { 0 , 0xdf000000 , 0xdfdf0000 , 0xdfdfdf00 , 0xdfdfdfdf } ;
151#else
152 static Standard_Integer Standard_Mask_Upper_Lower[5] =
153 { 0 , 0xdf , 0xdfdf , 0xdfdfdf , 0xdfdfdfdf } ;
154#endif
155
156//============================================================================
157//==== HashCode of a CString with discard of bit 5 (UpperCase<-->LowerCase)
158// Efficient for Types and MethodNames (without copy of characters)
159// Valid if we have only alphanumeric characters and "_" (unicity)
160// Valid if the Strings address is aligned for Integers
161//============================================================================
162Standard_Integer HASHCODES (const Standard_CString Value ,
163 const Standard_Integer Len )
164{
165 Standard_Integer aHashCode = 0 ;
166 Standard_Integer i = 0 ;
167
168 if (Value != NULL) {
169#ifdef ALIGNMENT_BUG
170 for ( i = 1 ; i <= Len >> 2 ; i++ ) {
171 aHashCode = aHashCode ^
172 ( ((Standard_Integer *) Value ) [ i - 1 ] &
173 Standard_Mask_Upper_Lower[4] ) ;
174 }
175 aHashCode = aHashCode ^
176 ( ((Standard_Integer *) Value ) [ i - 1 ] &
177 Standard_Mask_Upper_Lower[ Len & 3 ] ) ;
178#else
179 Standard_Integer itmp = 0 ;
180 for ( i = 0 ; i <= Len-4 ; i+=4 ) {
181 memcpy(&itmp,(const void *)&Value[i],4);
182 aHashCode=aHashCode^(itmp&Standard_Mask_Upper_Lower[4]);
183 }
184 if (Len&3) {
185 memcpy(&itmp,(const void *)&Value[i],Len&3);
186 aHashCode=aHashCode^(itmp&Standard_Mask_Upper_Lower[Len&3]);
187 }
188#endif
189
190 }
191 return aHashCode ;
192}
193
194//============================================================================
195// IsEqual : Returns Standard_True if two CString have the same value
196// Comparison is done with discard of bit 5 (UpperCase<-->LowerCase)
197// Efficient for Types and MethodNames (without copy of characters)
198// Valid if we have only alphanumeric characters and "_" (unicity)
199// Valid if the Strings address are aligned for Integers
200
201//============================================================================
202Standard_Boolean ISSIMILAR(const Standard_CString One ,
203 const Standard_Integer LenOne ,
204 const Standard_CString Two )
205{
206 Standard_Integer i ;
207
208#ifdef ALIGNMENT_BUG
209 for ( i = 1 ; i <= LenOne >> 2 ; i++ ) {
210 if ( (((Standard_Integer *) One ) [ i - 1 ] &
211 Standard_Mask_Upper_Lower[ 4 ] ) !=
212 (((Standard_Integer *) Two ) [ i - 1 ] &
213 Standard_Mask_Upper_Lower[ 4 ] ) )
214 return Standard_False ;
215 }
216 if ( (((Standard_Integer *) One ) [ i - 1 ] &
217 Standard_Mask_Upper_Lower[ LenOne & 3 ] ) !=
218 (((Standard_Integer *) Two ) [ i - 1 ] &
219 Standard_Mask_Upper_Lower[ LenOne & 3 ] ) )
220 return Standard_False ;
221#else
222 Standard_Integer iOne, iTwo ;
223 for ( i = 0; i <= LenOne-4; i+=4 ) {
224 memcpy(&iOne,(const void *)&One[i],4);
225 memcpy(&iTwo,(const void *)&Two[i],4);
226 if ((iOne&Standard_Mask_Upper_Lower[4] ) !=
227 (iTwo&Standard_Mask_Upper_Lower[4]))
228 return Standard_False;
229 }
230 if(LenOne&3) {
231 memcpy(&iOne,(const void *)&One[i],4);
232 memcpy(&iTwo,(const void *)&Two[i],4);
233 if ( (iOne&Standard_Mask_Upper_Lower[LenOne&3]) !=
234 (iTwo&Standard_Mask_Upper_Lower[LenOne&3]))
235 return Standard_False;
236 }
237#endif
238 return Standard_True ;
239}
240
241