2 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
3 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Paul Borman at Krystal Technologies.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 4. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 #include <sys/types.h>
52 _Read_RuneMagi(const char *fname
)
63 _FileRuneEntry
*runetype_ext_ranges
;
64 _FileRuneEntry
*maplower_ext_ranges
;
65 _FileRuneEntry
*mapupper_ext_ranges
;
66 int runetype_ext_len
= 0;
69 if ((fd
= open(fname
, O_RDONLY
)) < 0) {
74 if (fstat(fd
, &sb
) < 0) {
80 if ((size_t)sb
.st_size
< sizeof (_FileRuneLocale
)) {
87 fdata
= mmap(NULL
, sb
.st_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
94 frl
= (_FileRuneLocale
*)(void *)fdata
;
95 lastp
= fdata
+ sb
.st_size
;
99 if (memcmp(frl
->magic
, _FILE_RUNE_MAGIC_1
, sizeof (frl
->magic
))) {
103 runetype_ext_ranges
= (_FileRuneEntry
*)variable
;
104 variable
= runetype_ext_ranges
+ frl
->runetype_ext_nranges
;
105 if (variable
> lastp
) {
109 maplower_ext_ranges
= (_FileRuneEntry
*)variable
;
110 variable
= maplower_ext_ranges
+ frl
->maplower_ext_nranges
;
111 if (variable
> lastp
) {
115 mapupper_ext_ranges
= (_FileRuneEntry
*)variable
;
116 variable
= mapupper_ext_ranges
+ frl
->mapupper_ext_nranges
;
117 if (variable
> lastp
) {
121 frr
= runetype_ext_ranges
;
122 for (x
= 0; x
< frl
->runetype_ext_nranges
; ++x
) {
125 if (frr
[x
].map
== 0) {
126 int len
= frr
[x
].max
- frr
[x
].min
+ 1;
128 variable
= types
+ len
;
129 runetype_ext_len
+= len
;
130 if (variable
> lastp
) {
136 if ((char *)variable
+ frl
->variable_len
> (char *)lastp
) {
141 * Convert from disk format to host format.
143 data
= libc_malloc(sizeof (_RuneLocale
) +
144 (frl
->runetype_ext_nranges
+ frl
->maplower_ext_nranges
+
145 frl
->mapupper_ext_nranges
) * sizeof (_RuneEntry
) +
146 runetype_ext_len
* sizeof (*rr
->__types
) +
150 (void) munmap(fdata
, sb
.st_size
);
155 rl
= (_RuneLocale
*)(void *)data
;
156 rl
->__variable
= rl
+ 1;
158 (void) memcpy(rl
->__magic
, _RUNE_MAGIC_1
, sizeof (rl
->__magic
));
159 (void) memcpy(rl
->__encoding
, frl
->encoding
, sizeof (rl
->__encoding
));
161 rl
->__variable_len
= frl
->variable_len
;
162 rl
->__runetype_ext
.__nranges
= frl
->runetype_ext_nranges
;
163 rl
->__maplower_ext
.__nranges
= frl
->maplower_ext_nranges
;
164 rl
->__mapupper_ext
.__nranges
= frl
->mapupper_ext_nranges
;
166 for (x
= 0; x
< _CACHED_RUNES
; ++x
) {
167 rl
->__runetype
[x
] = frl
->runetype
[x
];
168 rl
->__maplower
[x
] = frl
->maplower
[x
];
169 rl
->__mapupper
[x
] = frl
->mapupper
[x
];
172 rl
->__runetype_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
173 rl
->__variable
= rl
->__runetype_ext
.__ranges
+
174 rl
->__runetype_ext
.__nranges
;
176 rl
->__maplower_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
177 rl
->__variable
= rl
->__maplower_ext
.__ranges
+
178 rl
->__maplower_ext
.__nranges
;
180 rl
->__mapupper_ext
.__ranges
= (_RuneEntry
*)rl
->__variable
;
181 rl
->__variable
= rl
->__mapupper_ext
.__ranges
+
182 rl
->__mapupper_ext
.__nranges
;
184 variable
= mapupper_ext_ranges
+ frl
->mapupper_ext_nranges
;
185 frr
= runetype_ext_ranges
;
186 rr
= rl
->__runetype_ext
.__ranges
;
187 for (x
= 0; x
< rl
->__runetype_ext
.__nranges
; ++x
) {
190 rr
[x
].__min
= frr
[x
].min
;
191 rr
[x
].__max
= frr
[x
].max
;
192 rr
[x
].__map
= frr
[x
].map
;
193 if (rr
[x
].__map
== 0) {
194 int len
= rr
[x
].__max
- rr
[x
].__min
+ 1;
196 variable
= types
+ len
;
197 rr
[x
].__types
= rl
->__variable
;
198 rl
->__variable
= rr
[x
].__types
+ len
;
200 rr
[x
].__types
[len
] = types
[len
];
202 rr
[x
].__types
= NULL
;
205 frr
= maplower_ext_ranges
;
206 rr
= rl
->__maplower_ext
.__ranges
;
207 for (x
= 0; x
< rl
->__maplower_ext
.__nranges
; ++x
) {
208 rr
[x
].__min
= frr
[x
].min
;
209 rr
[x
].__max
= frr
[x
].max
;
210 rr
[x
].__map
= frr
[x
].map
;
213 frr
= mapupper_ext_ranges
;
214 rr
= rl
->__mapupper_ext
.__ranges
;
215 for (x
= 0; x
< rl
->__mapupper_ext
.__nranges
; ++x
) {
216 rr
[x
].__min
= frr
[x
].min
;
217 rr
[x
].__max
= frr
[x
].max
;
218 rr
[x
].__map
= frr
[x
].map
;
221 (void) memcpy(rl
->__variable
, variable
, rl
->__variable_len
);
222 (void) munmap(fdata
, sb
.st_size
);
225 * Go out and zero pointers that should be zero.
227 if (!rl
->__variable_len
)
228 rl
->__variable
= NULL
;
230 if (!rl
->__runetype_ext
.__nranges
)
231 rl
->__runetype_ext
.__ranges
= NULL
;
233 if (!rl
->__maplower_ext
.__nranges
)
234 rl
->__maplower_ext
.__ranges
= NULL
;
236 if (!rl
->__mapupper_ext
.__nranges
)
237 rl
->__mapupper_ext
.__ranges
= NULL
;
242 (void) munmap(fdata
, sb
.st_size
);