0023024: Update headers of OCCT files
[occt.git] / src / Standard / Standard_CString.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 // Update JR 12-09-1997 :
21 //        - three methods of HashCoding of strings : we may keep the value
22 //          of the hashcode of the string itself. This value is used when
23 //          resizing of a Map or copying an item from a Map to another Map.
24 //        - three methods of HashCoding of strings converted to uppercase.
25
26 #define _Standard_CString_SourceFile
27
28 #define OptJr 1
29 #ifdef HAVE_CONFIG_H
30 # include <config.h>
31 #endif
32
33
34 #include <Standard_CString.hxx>
35 #include <Standard_Type.hxx> 
36 #include <Standard_OStream.hxx>
37
38 #if OptJr
39 # if defined(WORDS_BIGENDIAN)
40 static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
41                                                                  0xff000000 ,
42                                                                  0xffff0000 ,
43                                                                  0xffffff00 } ;
44 # else
45 static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
46                                                                  0x000000ff ,
47                                                                  0x0000ffff ,
48                                                                  0x00ffffff } ;
49 # endif
50 #endif
51
52 #include <Standard_String.hxx>
53 #include <string.h>
54
55 //============================================================================
56 //==== 
57 //============================================================================
58 const Handle_Standard_Type& Standard_CString_Type_() 
59 {
60   static Handle_Standard_Type _aType = 
61     new Standard_Type("Standard_CString",sizeof(Standard_CString),0,NULL);
62
63   return _aType;
64 }
65
66 //============================================================================
67 //==== ShallowDump : Writes a CString value.
68 //============================================================================
69 Standard_EXPORT void ShallowDump (const Standard_CString Value, Standard_OStream& s)
70 { s << Value << " Standard_CString " << "\n"; }
71
72 //============================================================================
73 //==== HashCode of a CString
74 //============================================================================
75 Standard_Integer HashCode (const Standard_CString Value, 
76                            const Standard_Integer Upper )
77 {
78   Standard_Integer aLen ;
79   //#if OptJr
80   //STRINGLEN( Value , aLen ) ;
81   //#else
82   aLen = (Standard_Integer)strlen(Value);
83   //#endif
84   return HashCode ( HashCodes( Value , aLen ) , Upper ) ;
85 }
86
87 #if OptJr
88 # if defined(WORDS_BIGENDIAN)
89   static Standard_Integer Standard_Mask_String_Left[4] =
90                   { 0 , 0x00ffffff , 0x0000ffff , 0x000000ff } ;
91   static Standard_Integer Standard_Mask_String_Right[4] =
92                   { 0 , 0xff000000 , 0xffff0000 , 0xffffff00 } ;
93 # else
94   static Standard_Integer Standard_Mask_String_Left[4] =
95                   { 0 , 0xffffff00 , 0xffff0000 , 0xff000000 } ;
96   static Standard_Integer Standard_Mask_String_Right[4] =
97                   { 0 , 0x000000ff , 0x0000ffff , 0x00ffffff } ;
98 # endif
99 #endif
100
101 //============================================================================
102 //==== HashCode of a CString
103 //============================================================================
104 Standard_Integer HashCodes (const Standard_CString Value ,
105                             const Standard_Integer Len )
106 {
107  Standard_Integer  aHashCode = 0 ;
108  Standard_Integer  i ;
109 #if !OptJr
110  char             *charPtr   = (char *)Value;
111  Standard_Integer  pos       = 0,
112                    count,
113                   *tmphash;
114  char              tabchar[20];
115 #endif
116   
117  if (Value != NULL) {
118
119 #if !OptJr
120    i = 0 ;
121    while (i < Len) {
122         for (count = 0,pos = i;count < sizeof(Standard_Integer); count++) {
123            if (pos + count >= Len)  tabchar[count] = '\0';
124            else tabchar[count] = charPtr[pos + count];
125            i++;
126          }
127         tmphash = (Standard_Integer *)tabchar;   
128         aHashCode = aHashCode ^ *tmphash;
129       }
130  }
131
132 #else
133    Standard_Integer *value = (Standard_Integer *)(ptrdiff_t(Value) & ~0x3) ;
134    Standard_Integer len = Len ;
135
136    unsigned int aResidue = (unsigned int)(ptrdiff_t(Value) & 0x3);
137    if (aResidue) {
138      aHashCode = *value & Standard_Mask_String_Left[aResidue] ;
139      value += 1 ;
140      len -= (4 - aResidue);
141    }
142
143    for ( i = 1 ; i <= len >> 2 ; i++ ) {
144       aHashCode = aHashCode ^ value[ i - 1 ] ;
145     }
146    aHashCode = aHashCode ^ ( value[ i - 1 ] &
147                Standard_Mask_String_Right[ len & 3 ] ) ;
148
149    if ( len != Len ) {
150 # if defined(WORDS_BIGENDIAN)
151      aHashCode = aHashCode << 8*aResidue |
152                  aHashCode >> 8*(4 - aResidue) ;
153 # else
154      aHashCode = aHashCode << 8*(4 - aResidue) |
155                  aHashCode >> 8*aResidue ;
156 # endif
157    }
158
159  }
160 #endif
161
162  return aHashCode ;
163 }
164
165
166 # if defined(WORDS_BIGENDIAN)
167  static Standard_Integer Standard_Mask_Upper_Lower[5] =
168                  { 0 , 0xdf000000 , 0xdfdf0000 , 0xdfdfdf00 , 0xdfdfdfdf } ;
169 #else
170  static Standard_Integer Standard_Mask_Upper_Lower[5] =
171                  { 0 , 0xdf , 0xdfdf , 0xdfdfdf , 0xdfdfdfdf } ;
172 #endif
173
174 //============================================================================
175 //==== HashCode of a CString with discard of bit 5 (UpperCase<-->LowerCase)
176 //     Efficient for Types and MethodNames (without copy of characters)
177 //     Valid if we have only alphanumeric characters and "_" (unicity)
178 //     Valid if the Strings address is aligned for Integers
179 //============================================================================
180 Standard_Integer HASHCODES (const Standard_CString Value ,
181                             const Standard_Integer Len )
182 {
183  Standard_Integer aHashCode = 0 ;
184  Standard_Integer i = 0 ;
185
186  if (Value != NULL) {
187 #ifdef ALIGNMENT_BUG
188    for ( i = 1 ; i <= Len >> 2 ; i++ ) {
189       aHashCode = aHashCode ^
190                   ( ((Standard_Integer *) Value ) [ i - 1 ] &
191                     Standard_Mask_Upper_Lower[4] ) ;
192     }
193    aHashCode = aHashCode ^
194                ( ((Standard_Integer *) Value ) [ i - 1 ] &
195                  Standard_Mask_Upper_Lower[ Len & 3 ] ) ;
196 #else
197    Standard_Integer itmp = 0 ;
198    for ( i = 0 ; i <= Len-4 ; i+=4 ) {
199       memcpy(&itmp,(const void *)&Value[i],4);
200       aHashCode=aHashCode^(itmp&Standard_Mask_Upper_Lower[4]);
201    }
202    if (Len&3) {
203       memcpy(&itmp,(const void *)&Value[i],Len&3);
204       aHashCode=aHashCode^(itmp&Standard_Mask_Upper_Lower[Len&3]);
205    }
206 #endif
207
208  }
209  return aHashCode ;
210 }
211
212 //============================================================================
213 // IsEqual : Returns Standard_True if two CString have the same value
214 // Comparison is done with discard of bit 5 (UpperCase<-->LowerCase)
215 // Efficient for Types and MethodNames (without copy of characters)
216 // Valid if we have only alphanumeric characters and "_" (unicity)
217 // Valid if the Strings address are aligned for Integers
218
219 //============================================================================
220 Standard_Boolean ISSIMILAR(const Standard_CString One ,
221                            const Standard_Integer LenOne ,
222                            const Standard_CString Two )
223 {
224   Standard_Integer i ;
225
226 #ifdef ALIGNMENT_BUG
227  for ( i = 1 ; i <= LenOne >> 2 ; i++ ) {
228     if ( (((Standard_Integer *) One ) [ i - 1 ] &
229          Standard_Mask_Upper_Lower[ 4 ] ) !=
230          (((Standard_Integer *) Two ) [ i - 1 ] &
231          Standard_Mask_Upper_Lower[ 4 ] ) )
232       return Standard_False ;
233   }
234  if ( (((Standard_Integer *) One ) [ i - 1 ] &
235       Standard_Mask_Upper_Lower[ LenOne & 3 ] ) !=
236       (((Standard_Integer *) Two ) [ i - 1 ] &
237       Standard_Mask_Upper_Lower[ LenOne & 3 ] ) )
238    return Standard_False  ;
239 #else
240   Standard_Integer  iOne, iTwo ;
241   for ( i = 0; i <= LenOne-4; i+=4 ) {
242     memcpy(&iOne,(const void *)&One[i],4);
243     memcpy(&iTwo,(const void *)&Two[i],4);
244     if ((iOne&Standard_Mask_Upper_Lower[4] ) !=
245         (iTwo&Standard_Mask_Upper_Lower[4]))
246       return Standard_False;
247   }
248   if(LenOne&3) {
249     memcpy(&iOne,(const void *)&One[i],4);
250     memcpy(&iTwo,(const void *)&Two[i],4);
251     if ( (iOne&Standard_Mask_Upper_Lower[LenOne&3]) !=
252          (iTwo&Standard_Mask_Upper_Lower[LenOne&3]))
253       return Standard_False;
254   }
255 #endif
256   return Standard_True ;
257 }
258
259