0025215: Porting to Android - fix minor issues
[occt.git] / src / Standard / Standard_CLocaleSentry.cxx
1 // Created on: 2013-01-17
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2013-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <Standard_CLocaleSentry.hxx>
17
18 #include <Standard_TypeDef.hxx>
19
20 #include <cstring>
21
22 #if !defined(__ANDROID__)
23
24 namespace
25 {
26
27   //! CLocalePtr - static object representing C locale
28   class CLocalePtr
29   {
30   public:
31
32     CLocalePtr()
33     #ifdef HAVE_XLOCALE_H
34     : myLocale (newlocale (LC_ALL_MASK, "C", NULL))
35     #elif defined(_WIN32)
36     : myLocale (_create_locale (LC_ALL, "C"))
37     #else
38     : myLocale (NULL)
39     #endif
40     {}
41
42     ~CLocalePtr()
43     {
44     #ifdef HAVE_XLOCALE_H
45       freelocale (myLocale);
46     #elif defined(_WIN32)
47       _free_locale (myLocale);
48     #endif
49     }
50
51   public:
52
53     Standard_CLocaleSentry::clocale_t myLocale;
54
55   };
56
57   static CLocalePtr theCLocale;
58
59 }
60
61 // =======================================================================
62 // function : GetCLocale
63 // purpose  :
64 // =======================================================================
65 Standard_CLocaleSentry::clocale_t Standard_CLocaleSentry::GetCLocale()
66 {
67   return theCLocale.myLocale;
68 }
69
70 // =======================================================================
71 // function : Standard_CLocaleSentry
72 // purpose  :
73 // =======================================================================
74 Standard_CLocaleSentry::Standard_CLocaleSentry()
75 #ifdef HAVE_XLOCALE_H
76 : myPrevLocale (uselocale (theCLocale.myLocale)) // switch to C locale within this thread only using xlocale API
77 #else
78 : myPrevLocale (setlocale (LC_ALL, 0))
79 #if defined(_MSC_VER) && (_MSC_VER > 1400)
80 , myPrevTLocaleState (_configthreadlocale (_ENABLE_PER_THREAD_LOCALE))
81 #endif
82 #endif
83 {
84 #if !defined(HAVE_XLOCALE_H)
85   const char* aPrevLocale = (const char* )myPrevLocale;
86   if (myPrevLocale == NULL
87    || (aPrevLocale[0] == 'C' && aPrevLocale[1] == '\0'))
88   {
89     myPrevLocale = NULL; // already C locale
90     return;
91   }
92   // copy string as following setlocale calls may invalidate returned pointer
93   Standard_Size aLen = std::strlen (aPrevLocale) + 1;
94   myPrevLocale = new char[aLen];
95   memcpy (myPrevLocale, aPrevLocale, aLen);
96
97   setlocale (LC_ALL, "C");
98 #endif
99 }
100
101 // =======================================================================
102 // function : ~Standard_CLocaleSentry
103 // purpose  :
104 // =======================================================================
105 Standard_CLocaleSentry::~Standard_CLocaleSentry()
106 {
107 #if defined(HAVE_XLOCALE_H)
108   uselocale ((locale_t )myPrevLocale);
109 #else
110   if (myPrevLocale != NULL)
111   {
112     const char* aPrevLocale = (const char* )myPrevLocale;
113     setlocale (LC_ALL, aPrevLocale);
114     delete[] aPrevLocale;
115   }
116 #if defined(_MSC_VER) && (_MSC_VER > 1400)
117   if (myPrevTLocaleState != _ENABLE_PER_THREAD_LOCALE)
118   {
119     _configthreadlocale (myPrevTLocaleState);
120   }
121 #endif
122 #endif
123 }
124
125 #endif // __ANDROID__