2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 /* CFStringDefaultEncoding.h
24 Copyright (c) 1998-2005, Apple, Inc. All rights reserved.
27 /* This file defines static inline functions used both by CarbonCore & CF. */
29 #include <CoreFoundation/CFBase.h>
34 #include <sys/param.h>
39 #if defined(__cplusplus)
43 #define __kCFUserEncodingEnvVariableName ("__CF_USER_TEXT_ENCODING")
44 #define __kCFMaxDefaultEncodingFileLength (24)
45 #define __kCFUserEncodingFileName ("/.CFUserTextEncoding")
47 /* This function is used to obtain users' default script/region code.
48 The function first looks at environment variable __kCFUserEncodingEnvVariableName, then, reads the configuration file in user's home directory.
50 CF_INLINE
void __CFStringGetUserDefaultEncoding(UInt32
*oScriptValue
, UInt32
*oRegionValue
) {
52 char buffer
[__kCFMaxDefaultEncodingFileLength
];
55 if ((stringValue
= getenv(__kCFUserEncodingEnvVariableName
)) != NULL
) {
56 if ((uid
== strtol(stringValue
, &stringValue
, 0)) && (':' == *stringValue
)) {
63 if ((stringValue
== NULL
) && ((uid
> 0) || getenv("HOME"))) {
64 struct passwd
*passwdp
;
66 if ((passwdp
= getpwuid((uid_t
)uid
))) {
67 char filename
[MAXPATHLEN
+ 1];
70 strcpy(filename
, passwdp
->pw_dir
);
71 strcat(filename
, __kCFUserEncodingFileName
);
73 if ((fd
= open(filename
, O_RDONLY
, 0)) == -1) {
74 // Cannot open the file. Let's fallback to smRoman/verUS
75 snprintf(filename
, sizeof(filename
), "%s=0x%X:0:0", __kCFUserEncodingEnvVariableName
, uid
);
80 // cjk: We do not turn on F_NOCACHE on the fd here, because
81 // many processes read this file on startup, and caching the
82 // is probably a good thing, for the system as a whole.
83 readSize
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength
- 1);
84 buffer
[(readSize
< 0 ? 0 : readSize
)] = '\0';
88 // Well, we already have a buffer, let's reuse it
89 snprintf(filename
, sizeof(filename
), "%s=0x%X:%s", __kCFUserEncodingEnvVariableName
, uid
, buffer
);
96 *oScriptValue
= strtol(stringValue
, &stringValue
, 0);
97 if (*stringValue
== ':') {
98 if (oRegionValue
) *oRegionValue
= strtol(++stringValue
, NULL
, 0);
104 *oScriptValue
= 0; // smRoman
105 if (oRegionValue
) *oRegionValue
= 0; // verUS
108 CF_INLINE
uint32_t __CFStringGetInstallationRegion() {
109 char *stringValue
= NULL
;
110 char buffer
[__kCFMaxDefaultEncodingFileLength
];
111 struct passwd
*passwdp
;
113 if ((passwdp
= getpwuid((uid_t
)0))) {
114 char filename
[MAXPATHLEN
+ 1];
117 strcpy(filename
, passwdp
->pw_dir
);
118 strcat(filename
, __kCFUserEncodingFileName
);
120 if ((fd
= open(filename
, O_RDONLY
, 0)) != -1) {
123 // cjk: We do not turn on F_NOCACHE on the fd here, because
124 // many processes read this file on startup, and caching the
125 // is probably a good thing, for the system as a whole.
126 readSize
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength
- 1);
127 buffer
[(readSize
< 0 ? 0 : readSize
)] = '\0';
129 stringValue
= buffer
;
134 (void)strtol(stringValue
, &stringValue
, 0);
135 if (*stringValue
== ':') return strtol(++stringValue
, NULL
, 0);
141 CF_INLINE
void __CFStringGetInstallationEncodingAndRegion(uint32_t *encoding
, uint32_t *region
) {
142 char *stringValue
= NULL
;
143 char buffer
[__kCFMaxDefaultEncodingFileLength
];
144 struct passwd
*passwdp
;
146 *encoding
= 0; *region
= 0;
148 if ((passwdp
= getpwuid((uid_t
)0))) {
149 char filename
[MAXPATHLEN
+ 1];
152 strcpy(filename
, passwdp
->pw_dir
);
153 strcat(filename
, __kCFUserEncodingFileName
);
155 if ((fd
= open(filename
, O_RDONLY
, 0)) != -1) {
158 // cjk: We do not turn on F_NOCACHE on the fd here, because
159 // many processes read this file on startup, and caching the
160 // is probably a good thing, for the system as a whole.
161 readSize
= read(fd
, buffer
, __kCFMaxDefaultEncodingFileLength
- 1);
162 buffer
[(readSize
< 0 ? 0 : readSize
)] = '\0';
164 stringValue
= buffer
;
169 *encoding
= strtol(stringValue
, &stringValue
, 0);
170 if (*stringValue
== ':') *region
= strtol(++stringValue
, NULL
, 0);
174 CF_INLINE
void __CFStringSaveUserDefaultEncoding(UInt32 iScriptValue
, UInt32 iRegionValue
) {
175 struct passwd
*passwdp
;
177 if ((passwdp
= getpwuid(getuid()))) {
178 char filename
[MAXPATHLEN
+ 1];
181 strcpy(filename
, passwdp
->pw_dir
);
182 strcat(filename
, __kCFUserEncodingFileName
);
184 // In case, file exists
185 (void)unlink(filename
);
187 if ((fd
= open(filename
, O_WRONLY
|O_CREAT
, 0400)) != -1) {
188 char buffer
[__kCFMaxDefaultEncodingFileLength
];
189 unsigned int writeSize
;
191 writeSize
= snprintf(buffer
, __kCFMaxDefaultEncodingFileLength
, "0x%X:0x%X", (unsigned int)iScriptValue
, (unsigned int)iRegionValue
);
192 (void)write(fd
, buffer
, (writeSize
> __kCFMaxDefaultEncodingFileLength
? __kCFMaxDefaultEncodingFileLength
: writeSize
));
198 #if defined(__cplusplus)
202 #endif /* __MACH__ */