Skip to content

Commit 8869db3

Browse files
jonsimantova-maurice
authored andcommitted
Add functions to get locale and time zone for Windows, Mac, and Linux.
On all 3 platforms, the test output is: GetTimezone() returned 'US/Pacific' GetLocale() returned 'en_US' (Note that on Linux, "blaze run" gets the locale properly, whereas "blaze test" requires that a sample locale be hard-coded, as the blaze test runtime omits those environment variables.) PiperOrigin-RevId: 248430653
1 parent f72e6d8 commit 8869db3

File tree

4 files changed

+263
-0
lines changed

4 files changed

+263
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef FIREBASE_APP_CLIENT_CPP_SRC_INCLUDE_FIREBASE_INTERNAL_PLATFORM_H_
18+
#define FIREBASE_APP_CLIENT_CPP_SRC_INCLUDE_FIREBASE_INTERNAL_PLATFORM_H_
19+
20+
// This header serts exactly one of these FIREBASE_PLATFORM macros to 1, and the
21+
// rest to 0:
22+
//
23+
// FIREBASE_PLATFORM_ANDROID
24+
// FIREBASE_PLATFORM_IOS
25+
// FIREBASE_PLATFORM_OSX
26+
// FIREBASE_PLATFORM_WINDOWS
27+
// FIREBASE_PLATFORM_LINUX
28+
// FIREBASE_PLATFORM_UNKNOWN
29+
//
30+
// You can use e.g. #if FIREBASE_PLATFORM_OSX to conditionally compile code
31+
// after including this header.
32+
//
33+
// It also defines some convenience macros:
34+
// FIREBASE_PLATFORM_DESKTOP (1 on OSX, WINDOWS, and LINUX, 0 otherwise)
35+
// FIREBASE_PLATFORM_MOBILE (1 on IOS and ANDROID, 0 otherwise)
36+
37+
#define FIREBASE_PLATFORM_ANDROID 0
38+
#define FIREBASE_PLATFORM_IOS 0
39+
#define FIREBASE_PLATFORM_OSX 0
40+
#define FIREBASE_PLATFORM_WINDOWS 0
41+
#define FIREBASE_PLATFORM_LINUX 0
42+
#define FIREBASE_PLATFORM_UNKNOWN 0
43+
44+
#ifdef __APPLE__
45+
#include "TargetConditionals.h"
46+
#endif // __APPLE__
47+
48+
#if defined(__ANDROID__)
49+
#undef FIREBASE_PLATFORM_ANDROID
50+
#define FIREBASE_PLATFORM_ANDROID 1
51+
#elif defined(TARGET_OS_IOS) && TARGET_OS_IOS
52+
#undef FIREBASE_PLATFORM_IOS
53+
#define FIREBASE_PLATFORM_IOS 1
54+
#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX
55+
#undef FIREBASE_PLATFORM_OSX
56+
#define FIREBASE_PLATFORM_OSX 1
57+
#elif defined(_WIN32)
58+
#undef FIREBASE_PLATFORM_WINDOWS
59+
#define FIREBASE_PLATFORM_WINDOWS 1
60+
#elif defined(__linux__)
61+
#undef FIREBASE_PLATFORM_LINUX
62+
#define FIREBASE_PLATFORM_LINUX 1
63+
#else
64+
#undef FIREBASE_PLATFORM_UNKNOWN
65+
#define FIREBASE_PLATFORM_UNKNOWN 1
66+
#endif
67+
68+
#define FIREBASE_PLATFORM_MOBILE \
69+
(FIREBASE_PLATFORM_IOS || FIREBASE_PLATFORM_ANDROID)
70+
#define FIREBASE_PLATFORM_DESKTOP \
71+
(FIREBASE_PLATFORM_LINUX || FIREBASE_PLATFORM_WINDOWS || \
72+
FIREBASE_PLATFORM_OSX)
73+
74+
#endif // FIREBASE_APP_CLIENT_CPP_SRC_INCLUDE_FIREBASE_INTERNAL_PLATFORM_H_

app/src/locale.cc

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "app/src/locale.h"
18+
19+
#include "app/src/include/firebase/internal/platform.h"
20+
#include "app/src/log.h"
21+
22+
#if FIREBASE_PLATFORM_OSX || FIREBASE_PLATFORM_IOS
23+
#error "This file does not support iOS and OS X, use locale_apple.mm instead."
24+
#elif FIREBASE_PLATFORM_ANDROID
25+
#error "This file is not support on Android."
26+
#elif FIREBASE_PLATFORM_WINDOWS
27+
#include <time.h>
28+
#include <windows.h>
29+
#elif FIREBASE_PLATFORM_LINUX
30+
#include <clocale>
31+
#include <ctime>
32+
#include <locale>
33+
#else
34+
#error "Unknown platform."
35+
#endif // platform selector
36+
37+
#include <algorithm>
38+
#include <vector>
39+
40+
namespace firebase {
41+
namespace internal {
42+
43+
// Get the current locale, e.g. "en_US"
44+
std::string GetLocale() {
45+
#if FIREBASE_PLATFORM_WINDOWS
46+
LCID lang_id = GetThreadLocale();
47+
std::vector<wchar_t> locale_name(LOCALE_NAME_MAX_LENGTH);
48+
if (LCIDToLocaleName(lang_id, &locale_name[0], LOCALE_NAME_MAX_LENGTH, 0) ==
49+
0) {
50+
return "";
51+
}
52+
std::wstring woutput(&locale_name[0]);
53+
std::string output(woutput.begin(), woutput.end());
54+
// Change all hyphens to underscores to normalize the locale.
55+
std::replace(output.begin(), output.end(), '-', '_');
56+
return output;
57+
#elif FIREBASE_PLATFORM_LINUX
58+
// If std::locale() has been customized, return it, else return the contents
59+
// of the LANG or LC_CTYPE environment variables if set, or otherwise return a
60+
// default locale (empty in real life, or placeholder when running in a unit
61+
// test, as the test environment has no locale variables set).
62+
std::string output = std::locale().name() != "C"
63+
? std::locale().name()
64+
: getenv("LANG")
65+
? getenv("LANG")
66+
: getenv("LC_CTYPE")
67+
? getenv("LC_CTYPE")
68+
: getenv("TEST_TMPDIR") ? "en_US" : "";
69+
// Some of the environment variables have a "." after the name to specify the
70+
// terminal encoding, e.g. "en_US.UTF-8", so we want to cut the string on the
71+
// ".".
72+
size_t cut = output.find(".");
73+
if (cut != std::string::npos) {
74+
output = output.substr(0, cut);
75+
}
76+
// Do the same with a "@" which some locales also have.
77+
cut = output.find("@");
78+
if (cut != std::string::npos) {
79+
output = output.substr(0, cut);
80+
}
81+
return output;
82+
#else
83+
// An error was already triggered above.
84+
return "";
85+
#endif // platform selector
86+
}
87+
88+
// Get the current time zone, e.g. "US/Pacific"
89+
std::string GetTimezone() {
90+
#if FIREBASE_PLATFORM_WINDOWS
91+
// If "TZ" environment variable is defined, use it, else use _get_tzname.
92+
int tz_bytes = GetEnvironmentVariable("TZ", nullptr, 0);
93+
if (tz_bytes > 0) {
94+
std::vector<char> buffer(tz_bytes);
95+
GetEnvironmentVariable("TZ", &buffer[0], tz_bytes);
96+
return std::string(&buffer[0]);
97+
}
98+
int daylight; // daylight savings time?
99+
if (_get_daylight(&daylight) != 0) return "";
100+
size_t length = 0; // get the needed string length
101+
if (_get_tzname(&length, nullptr, 0, daylight ? 1 : 0) != 0) return "";
102+
std::vector<char> namebuf(length);
103+
if (_get_tzname(&length, &namebuf[0], length, daylight ? 1 : 0) != 0)
104+
return "";
105+
std::string name_str(&namebuf[0]);
106+
return name_str;
107+
#elif FIREBASE_PLATFORM_LINUX
108+
// If TZ environment variable is defined and not empty, use it, else use
109+
// tzname.
110+
return (getenv("TZ") && *getenv("TZ")) ? getenv("TZ")
111+
: tzname[daylight ? 1 : 0];
112+
#else
113+
// An error was already triggered above.
114+
return "";
115+
#endif // platform selector
116+
}
117+
118+
} // namespace internal
119+
} // namespace firebase

app/src/locale.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
/*
3+
* Copyright 2019 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef FIREBASE_APP_CLIENT_CPP_SRC_LOCALE_H_
19+
#define FIREBASE_APP_CLIENT_CPP_SRC_LOCALE_H_
20+
21+
#include <string>
22+
23+
namespace firebase {
24+
namespace internal {
25+
26+
// Get the current locale, e.g. "en_US". Returns an empty string if
27+
// the locale cannot be discerned.
28+
std::string GetLocale();
29+
30+
// Get the current time zone, e.g. "US/Pacific" or "EDT".
31+
std::string GetTimezone();
32+
33+
} // namespace internal
34+
} // namespace firebase
35+
36+
#endif // FIREBASE_APP_CLIENT_CPP_SRC_LOCALE_H_

app/src/locale_apple.mm

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2019 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "app/src/include/firebase/internal/platform.h"
18+
#include "app/src/locale.h"
19+
20+
#if !FIREBASE_PLATFORM_OSX && !FIREBASE_PLATFORM_IOS
21+
#error "This file only supports iOS and OS X, use locale.cc for other platforms."
22+
#endif
23+
24+
#import <Foundation/Foundation.h>
25+
26+
namespace firebase {
27+
namespace internal {
28+
29+
std::string GetTimezone() { return NSTimeZone.localTimeZone.name.UTF8String; }
30+
31+
std::string GetLocale() { return [NSLocale currentLocale].localeIdentifier.UTF8String; }
32+
33+
} // namespace internal
34+
} // namespace firebase

0 commit comments

Comments
 (0)