summaryrefslogtreecommitdiff
path: root/src/Standard/Standard_CString.cxx
blob: 19b30719ddddcba4485ad86409b4707b6dd9f32e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

// Update JR 12-09-1997 :
//        - three methods of HashCoding of strings : we may keep the value
//          of the hashcode of the string itself. This value is used when
//          resizing of a Map or copying an item from a Map to another Map.
//        - three methods of HashCoding of strings converted to uppercase.

#define _Standard_CString_SourceFile

#define OptJr 1
#ifdef HAVE_CONFIG_H
# include <oce-config.h>
#endif


#include <Standard_CString.hxx>
#include <Standard_Type.hxx> 
#include <Standard_OStream.hxx>

#if OptJr
# if defined(WORDS_BIGENDIAN)
static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
                                                                 0xff000000 ,
                                                                 0xffff0000 ,
                                                                 0xffffff00 } ;
# else
static const Standard_Integer static_MaskEndIntegerString[4] = { 0x00000000 ,
                                                                 0x000000ff ,
                                                                 0x0000ffff ,
                                                                 0x00ffffff } ;
# endif
#endif

#include <Standard_String.hxx>
#include <string.h>

//============================================================================
//==== 
//============================================================================
Handle_Standard_Type& Standard_CString_Type_() 
{
  static Handle_Standard_Type _aType = 
    new Standard_Type("Standard_CString",sizeof(Standard_CString),0,NULL);

  return _aType;
}

//============================================================================
//==== ShallowDump : Writes a CString value.
//============================================================================
Standard_EXPORT void ShallowDump (const Standard_CString Value, Standard_OStream& s)
{ s << Value << " Standard_CString " << "\n"; }

//============================================================================
//==== HashCode of a CString
//============================================================================
Standard_Integer HashCode (const Standard_CString Value, 
                           const Standard_Integer Upper )
{
  Standard_Integer aLen ;
  //#if OptJr
  //STRINGLEN( Value , aLen ) ;
  //#else
  aLen = (Standard_Integer)strlen(Value);
  //#endif
  return HashCode ( HashCodes( Value , aLen ) , Upper ) ;
}

#if OptJr
# if defined(WORDS_BIGENDIAN)
  static Standard_Integer Standard_Mask_String_Left[4] =
                  { 0 , 0x00ffffff , 0x0000ffff , 0x000000ff } ;
  static Standard_Integer Standard_Mask_String_Right[4] =
                  { 0 , 0xff000000 , 0xffff0000 , 0xffffff00 } ;
# else
  static Standard_Integer Standard_Mask_String_Left[4] =
                  { 0 , 0xffffff00 , 0xffff0000 , 0xff000000 } ;
  static Standard_Integer Standard_Mask_String_Right[4] =
                  { 0 , 0x000000ff , 0x0000ffff , 0x00ffffff } ;
# endif
#endif

//============================================================================
//==== HashCode of a CString
//============================================================================
Standard_Integer HashCodes (const Standard_CString Value ,
                            const Standard_Integer Len )
{
 Standard_Integer  aHashCode = 0 ;
 Standard_Integer  i ;
#if !OptJr
 char             *charPtr   = (char *)Value;
 Standard_Integer  pos       = 0,
                   count,
                  *tmphash;
 char              tabchar[20];
#endif
  
 if (Value != NULL) {

#if !OptJr
   i = 0 ;
   while (i < Len) {
        for (count = 0,pos = i;count < sizeof(Standard_Integer); count++) {
           if (pos + count >= Len)  tabchar[count] = '\0';
           else tabchar[count] = charPtr[pos + count];
           i++;
	 }
        tmphash = (Standard_Integer *)tabchar;   
        aHashCode = aHashCode ^ *tmphash;
      }
 }

#else
   Standard_Integer *value = (Standard_Integer *)(ptrdiff_t(Value) & ~0x3) ;
   Standard_Integer len = Len ;

   unsigned int aResidue = (unsigned int)(ptrdiff_t(Value) & 0x3);
   if (aResidue) {
     aHashCode = *value & Standard_Mask_String_Left[aResidue] ;
     value += 1 ;
     len -= (4 - aResidue);
   }

   for ( i = 1 ; i <= len >> 2 ; i++ ) {
      aHashCode = aHashCode ^ value[ i - 1 ] ;
    }
   aHashCode = aHashCode ^ ( value[ i - 1 ] &
               Standard_Mask_String_Right[ len & 3 ] ) ;

   if ( len != Len ) {
# if defined(WORDS_BIGENDIAN)
     aHashCode = aHashCode << 8*aResidue |
                 aHashCode >> 8*(4 - aResidue) ;
# else
     aHashCode = aHashCode << 8*(4 - aResidue) |
                 aHashCode >> 8*aResidue ;
# endif
   }

 }
#endif

 return aHashCode ;
}


# if defined(WORDS_BIGENDIAN)
 static Standard_Integer Standard_Mask_Upper_Lower[5] =
                 { 0 , 0xdf000000 , 0xdfdf0000 , 0xdfdfdf00 , 0xdfdfdfdf } ;
#else
 static Standard_Integer Standard_Mask_Upper_Lower[5] =
                 { 0 , 0xdf , 0xdfdf , 0xdfdfdf , 0xdfdfdfdf } ;
#endif

//============================================================================
//==== HashCode of a CString with discard of bit 5 (UpperCase<-->LowerCase)
//     Efficient for Types and MethodNames (without copy of characters)
//     Valid if we have only alphanumeric characters and "_" (unicity)
//     Valid if the Strings address is aligned for Integers
//============================================================================
Standard_Integer HASHCODES (const Standard_CString Value ,
                            const Standard_Integer Len )
{
 Standard_Integer aHashCode = 0 ;
 Standard_Integer i = 0 ;

 if (Value != NULL) {
#ifdef ALIGNMENT_BUG
   for ( i = 1 ; i <= Len >> 2 ; i++ ) {
      aHashCode = aHashCode ^
                  ( ((Standard_Integer *) Value ) [ i - 1 ] &
                    Standard_Mask_Upper_Lower[4] ) ;
    }
   aHashCode = aHashCode ^
               ( ((Standard_Integer *) Value ) [ i - 1 ] &
                 Standard_Mask_Upper_Lower[ Len & 3 ] ) ;
#else
   Standard_Integer itmp = 0 ;
   for ( i = 0 ; i <= Len-4 ; i+=4 ) {
      memcpy(&itmp,(const void *)&Value[i],4);
      aHashCode=aHashCode^(itmp&Standard_Mask_Upper_Lower[4]);
   }
   if (Len&3) {
      memcpy(&itmp,(const void *)&Value[i],Len&3);
      aHashCode=aHashCode^(itmp&Standard_Mask_Upper_Lower[Len&3]);
   }
#endif

 }
 return aHashCode ;
}

//============================================================================
// IsEqual : Returns Standard_True if two CString have the same value
// Comparison is done with discard of bit 5 (UpperCase<-->LowerCase)
// Efficient for Types and MethodNames (without copy of characters)
// Valid if we have only alphanumeric characters and "_" (unicity)
// Valid if the Strings address are aligned for Integers

//============================================================================
Standard_Boolean ISSIMILAR(const Standard_CString One ,
                           const Standard_Integer LenOne ,
                           const Standard_CString Two )
{
  Standard_Integer i ;

#ifdef ALIGNMENT_BUG
 for ( i = 1 ; i <= LenOne >> 2 ; i++ ) {
    if ( (((Standard_Integer *) One ) [ i - 1 ] &
         Standard_Mask_Upper_Lower[ 4 ] ) !=
         (((Standard_Integer *) Two ) [ i - 1 ] &
         Standard_Mask_Upper_Lower[ 4 ] ) )
      return Standard_False ;
  }
 if ( (((Standard_Integer *) One ) [ i - 1 ] &
      Standard_Mask_Upper_Lower[ LenOne & 3 ] ) !=
      (((Standard_Integer *) Two ) [ i - 1 ] &
      Standard_Mask_Upper_Lower[ LenOne & 3 ] ) )
   return Standard_False  ;
#else
  Standard_Integer  iOne, iTwo ;
  for ( i = 0; i <= LenOne-4; i+=4 ) {
    memcpy(&iOne,(const void *)&One[i],4);
    memcpy(&iTwo,(const void *)&Two[i],4);
    if ((iOne&Standard_Mask_Upper_Lower[4] ) !=
	(iTwo&Standard_Mask_Upper_Lower[4]))
      return Standard_False;
  }
  if(LenOne&3) {
    memcpy(&iOne,(const void *)&One[i],4);
    memcpy(&iTwo,(const void *)&Two[i],4);
    if ( (iOne&Standard_Mask_Upper_Lower[LenOne&3]) !=
	 (iTwo&Standard_Mask_Upper_Lower[LenOne&3]))
      return Standard_False;
  }
#endif
  return Standard_True ;
}