]> git.saurik.com Git - apple/cf.git/blob - String.subproj/CFStringDefaultEncoding.h
CF-368.27.tar.gz
[apple/cf.git] / String.subproj / CFStringDefaultEncoding.h
1 /*
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /* CFStringDefaultEncoding.h
24 Copyright (c) 1998-2005, Apple, Inc. All rights reserved.
25 */
26
27 /* This file defines static inline functions used both by CarbonCore & CF. */
28
29 #include <CoreFoundation/CFBase.h>
30 #if defined(__MACH__)
31 #include <stdlib.h>
32 #include <fcntl.h>
33 #include <pwd.h>
34 #include <sys/param.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include <stdio.h>
38
39 #if defined(__cplusplus)
40 extern "C" {
41 #endif
42
43 #define __kCFUserEncodingEnvVariableName ("__CF_USER_TEXT_ENCODING")
44 #define __kCFMaxDefaultEncodingFileLength (24)
45 #define __kCFUserEncodingFileName ("/.CFUserTextEncoding")
46
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.
49 */
50 CF_INLINE void __CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue) {
51 char *stringValue;
52 char buffer[__kCFMaxDefaultEncodingFileLength];
53 int uid = getuid();
54
55 if ((stringValue = getenv(__kCFUserEncodingEnvVariableName)) != NULL) {
56 if ((uid == strtol(stringValue, &stringValue, 0)) && (':' == *stringValue)) {
57 ++stringValue;
58 } else {
59 stringValue = NULL;
60 }
61 }
62
63 if ((stringValue == NULL) && ((uid > 0) || getenv("HOME"))) {
64 struct passwd *passwdp;
65
66 if ((passwdp = getpwuid((uid_t)uid))) {
67 char filename[MAXPATHLEN + 1];
68 int fd;
69
70 strcpy(filename, passwdp->pw_dir);
71 strcat(filename, __kCFUserEncodingFileName);
72
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);
76 putenv(filename);
77 } else {
78 int readSize;
79
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';
85 close(fd);
86 stringValue = buffer;
87
88 // Well, we already have a buffer, let's reuse it
89 snprintf(filename, sizeof(filename), "%s=0x%X:%s", __kCFUserEncodingEnvVariableName, uid, buffer);
90 putenv(filename);
91 }
92 }
93 }
94
95 if (stringValue) {
96 *oScriptValue = strtol(stringValue, &stringValue, 0);
97 if (*stringValue == ':') {
98 if (oRegionValue) *oRegionValue = strtol(++stringValue, NULL, 0);
99 return;
100 }
101 }
102
103 // Falling back
104 *oScriptValue = 0; // smRoman
105 if (oRegionValue) *oRegionValue = 0; // verUS
106 }
107
108 CF_INLINE uint32_t __CFStringGetInstallationRegion() {
109 char *stringValue = NULL;
110 char buffer[__kCFMaxDefaultEncodingFileLength];
111 struct passwd *passwdp;
112
113 if ((passwdp = getpwuid((uid_t)0))) {
114 char filename[MAXPATHLEN + 1];
115 int fd;
116
117 strcpy(filename, passwdp->pw_dir);
118 strcat(filename, __kCFUserEncodingFileName);
119
120 if ((fd = open(filename, O_RDONLY, 0)) != -1) {
121 int readSize;
122
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';
128 close(fd);
129 stringValue = buffer;
130 }
131 }
132
133 if (stringValue) {
134 (void)strtol(stringValue, &stringValue, 0);
135 if (*stringValue == ':') return strtol(++stringValue, NULL, 0);
136 }
137
138 return 0; // verUS
139 }
140
141 CF_INLINE void __CFStringGetInstallationEncodingAndRegion(uint32_t *encoding, uint32_t *region) {
142 char *stringValue = NULL;
143 char buffer[__kCFMaxDefaultEncodingFileLength];
144 struct passwd *passwdp;
145
146 *encoding = 0; *region = 0;
147
148 if ((passwdp = getpwuid((uid_t)0))) {
149 char filename[MAXPATHLEN + 1];
150 int fd;
151
152 strcpy(filename, passwdp->pw_dir);
153 strcat(filename, __kCFUserEncodingFileName);
154
155 if ((fd = open(filename, O_RDONLY, 0)) != -1) {
156 int readSize;
157
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';
163 close(fd);
164 stringValue = buffer;
165 }
166 }
167
168 if (stringValue) {
169 *encoding = strtol(stringValue, &stringValue, 0);
170 if (*stringValue == ':') *region = strtol(++stringValue, NULL, 0);
171 }
172 }
173
174 CF_INLINE void __CFStringSaveUserDefaultEncoding(UInt32 iScriptValue, UInt32 iRegionValue) {
175 struct passwd *passwdp;
176
177 if ((passwdp = getpwuid(getuid()))) {
178 char filename[MAXPATHLEN + 1];
179 int fd;
180
181 strcpy(filename, passwdp->pw_dir);
182 strcat(filename, __kCFUserEncodingFileName);
183
184 // In case, file exists
185 (void)unlink(filename);
186
187 if ((fd = open(filename, O_WRONLY|O_CREAT, 0400)) != -1) {
188 char buffer[__kCFMaxDefaultEncodingFileLength];
189 unsigned int writeSize;
190
191 writeSize = snprintf(buffer, __kCFMaxDefaultEncodingFileLength, "0x%X:0x%X", (unsigned int)iScriptValue, (unsigned int)iRegionValue);
192 (void)write(fd, buffer, (writeSize > __kCFMaxDefaultEncodingFileLength ? __kCFMaxDefaultEncodingFileLength : writeSize));
193 close(fd);
194 }
195 }
196 }
197
198 #if defined(__cplusplus)
199 }
200 #endif
201
202 #endif /* __MACH__ */