0029399: Optimize reading of floating point values from text strings
[occt.git] / src / Standard / Standard_CString.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2013 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 // Update JR 12-09-1997 :
16 //        - three methods of HashCoding of strings : we may keep the value
17 //          of the hashcode of the string itself. This value is used when
18 //          resizing of a Map or copying an item from a Map to another Map.
19 //        - three methods of HashCoding of strings converted to uppercase.
20
21 #include <Standard_Type.hxx>
22
23 #include <Standard_CLocaleSentry.hxx>
24 #include <Standard_CString.hxx>
25 #include <Standard_Type.hxx>
26 #include <Standard_OStream.hxx>
27 #include <string.h>
28 #include <stdarg.h>
29
30 //============================================================================
31 //==== HashCode of a CString
32 //============================================================================
33 Standard_Integer HashCode (const Standard_CString Value,
34                            const Standard_Integer Upper )
35 {
36   Standard_Integer aLen = (Standard_Integer)strlen(Value);
37   return HashCode (HashCodes (Value, aLen), Upper);
38 }
39
40 //============================================================================
41 //==== HashCode of a CString
42 //============================================================================
43 Standard_Integer HashCodes (const Standard_CString Value,
44                             const Standard_Integer Len)
45 {
46   // compute DJB2 hash of a string
47   Standard_Integer hash = 0;
48   const Standard_Character *c = Value;
49   for (Standard_Integer i = 0; i < Len; i++, c++)
50   {
51     /* hash = hash * 33 ^ c */
52     hash = ((hash << 5) + hash) ^ (*c);
53   }
54
55   return hash;
56 }
57
58 //======================================================================
59 // Locale-independent equivalents of C functions dealing with conversion
60 // of string to real and vice-versa
61 //======================================================================
62
63 #ifdef __APPLE__
64   // There are a lot of *_l functions availalbe on Mac OS X - we use them
65   #define SAVE_TL()
66 #elif defined(_MSC_VER)
67   // MSVCRT has equivalents with slightly different syntax
68   #define SAVE_TL()
69   #define strtod_l(thePtr, theNextPtr, theLocale)                _strtod_l(thePtr, theNextPtr, theLocale)
70   #define vprintf_l(theLocale, theFormat, theArgPtr)             _vprintf_l(theFormat, theLocale, theArgPtr)
71   #define vsprintf_l(theBuffer, theLocale, theFormat, theArgPtr) _vsprintf_l(theBuffer, theFormat, theLocale, theArgPtr)
72   #define vfprintf_l(theFile,   theLocale, theFormat, theArgPtr) _vfprintf_l(theFile,   theFormat, theLocale, theArgPtr)
73 #else
74   // glibc provides only limited xlocale implementation:
75   // strtod_l/strtol_l/strtoll_l functions with explicitly specified locale
76   // and newlocale/uselocale/freelocale to switch locale within current thread only.
77   // So we switch to C locale temporarily
78   #define SAVE_TL() Standard_CLocaleSentry aLocaleSentry;
79   #ifndef OCCT_CLOCALE_POSIX2008
80     // glibc version for android platform use locale-independent implementation of
81     // strtod, strtol, strtoll functions. For other system with locale-depended
82     // implementations problems may appear if "C" locale is not set explicitly.
83     #if !defined(__ANDROID__) && !defined(__QNX__) && !defined(__MINGW32__)
84       #error System does not support xlocale. Import/export could be broken if C locale did not specified by application.
85     #endif
86     #define strtod_l(thePtr, theNextPtr, theLocale)              strtod(thePtr, theNextPtr)
87   #endif
88   #define vprintf_l(theLocale, theFormat, theArgPtr)             vprintf(theFormat, theArgPtr)
89   #define vsprintf_l(theBuffer, theLocale, theFormat, theArgPtr) vsprintf(theBuffer, theFormat, theArgPtr)
90   #define vfprintf_l(theFile,   theLocale, theFormat, theArgPtr) vfprintf(theFile,   theFormat, theArgPtr)
91 #endif
92
93 /*
94 double Strtod (const char* theStr, char** theNextPtr)
95 {
96   return strtod_l (theStr, theNextPtr, Standard_CLocaleSentry::GetCLocale());
97 }
98 */
99
100 double Atof (const char* theStr)
101 {
102   return Strtod (theStr, NULL);
103 }
104
105 int Printf  (const Standard_CString theFormat, ...)
106 {
107   SAVE_TL();
108   va_list argp;
109   va_start(argp, theFormat);
110   int result = vprintf_l (Standard_CLocaleSentry::GetCLocale(), theFormat, argp);
111   va_end(argp);
112   return result;
113 }
114
115 int Fprintf (FILE* theFile, const char* theFormat, ...)
116 {
117   SAVE_TL();
118   va_list argp;
119   va_start(argp, theFormat);
120   int result = vfprintf_l(theFile, Standard_CLocaleSentry::GetCLocale(), theFormat, argp);
121   va_end(argp);
122   return result;
123 }
124
125 int Sprintf (char* theBuffer, const char* theFormat, ...)
126 {
127   SAVE_TL();
128   va_list argp;
129   va_start(argp, theFormat);
130   int result = vsprintf_l(theBuffer, Standard_CLocaleSentry::GetCLocale(), theFormat, argp);
131   va_end(argp);
132   return result;
133 }