1/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrAutoLocaleSetter_DEFINED
9#define GrAutoLocaleSetter_DEFINED
10
11#include "GrTypes.h"
12
13#if defined(SK_BUILD_FOR_WIN)
14#include "SkString.h"
15#endif
16
17#if !defined(SK_BUILD_FOR_ANDROID)
18#include <locale.h>
19#endif
20
21#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
22#include <xlocale.h>
23#endif
24
25#if defined(SK_BUILD_FOR_ANDROID) || defined(__UCLIBC__) || defined(_NEWLIB_VERSION)
26#define HAVE_LOCALE_T 0
27#else
28#define HAVE_LOCALE_T 1
29#endif
30
31/**
32 * Helper class for ensuring that we don't use the wrong locale when building shaders. Android
33 * doesn't support locale in the NDK, so this is a no-op there.
34 */
35class GrAutoLocaleSetter : public SkNoncopyable {
36public:
37    GrAutoLocaleSetter (const char* name) {
38#if defined(SK_BUILD_FOR_WIN)
39        fOldPerThreadLocale = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
40        char* oldLocale = setlocale(LC_ALL, name);
41        if (oldLocale) {
42            fOldLocale = oldLocale;
43            fShouldRestoreLocale = true;
44        } else {
45            fShouldRestoreLocale = false;
46        }
47#elif HAVE_LOCALE_T
48        fLocale = newlocale(LC_ALL, name, 0);
49        if (fLocale) {
50            fOldLocale = uselocale(fLocale);
51        } else {
52            fOldLocale = static_cast<locale_t>(0);
53        }
54#else
55        (void) name; // suppress unused param warning.
56#endif
57    }
58
59    ~GrAutoLocaleSetter () {
60#if defined(SK_BUILD_FOR_WIN)
61        if (fShouldRestoreLocale) {
62            setlocale(LC_ALL, fOldLocale.c_str());
63        }
64        _configthreadlocale(fOldPerThreadLocale);
65#elif HAVE_LOCALE_T
66        if (fLocale) {
67             uselocale(fOldLocale);
68             freelocale(fLocale);
69        }
70#endif
71    }
72
73private:
74#if defined(SK_BUILD_FOR_WIN)
75    int fOldPerThreadLocale;
76    bool fShouldRestoreLocale;
77    SkString fOldLocale;
78#elif HAVE_LOCALE_T
79    locale_t fOldLocale;
80    locale_t fLocale;
81#endif
82};
83
84#undef HAVE_LOCALE_T
85
86#endif
87
88