Skip to main content

nt_hive/
string.rs

1// Copyright 2019-2025 Colin Finck <colin@reactos.org>
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4use core::char;
5use core::cmp::Ordering;
6use core::fmt;
7
8#[cfg(feature = "alloc")]
9use alloc::string::String;
10
11/// Sorted table of lowercase Basic Multilingual Plane (BMP) character code points and their uppercase equivalents.
12/// This is what Windows registry hives use to perform case-insensitive comparisons.
13///
14/// Generated by a modified version of
15/// https://github.com/rust-lang/rust/tree/0d97f7a96877a96015d70ece41ad08bb7af12377/src/tools/unicode-table-generator
16///
17/// In contrast to the original UPPERCASE_TABLE in core::unicode and char::to_uppercase, this table
18/// - only considers one-to-one mappings from UnicodeData.txt, but none of SpecialCasing.txt
19/// - only encompasses the Unicode Basic Multilingual Plane (BMP, first 0xffff characters)
20/// - uses `u16` instead of `char` for space efficiency
21static BMP_UPPERCASE_TABLE: &[(u16, u16)] = &[
22    (0x61, 0x41),
23    (0x62, 0x42),
24    (0x63, 0x43),
25    (0x64, 0x44),
26    (0x65, 0x45),
27    (0x66, 0x46),
28    (0x67, 0x47),
29    (0x68, 0x48),
30    (0x69, 0x49),
31    (0x6a, 0x4a),
32    (0x6b, 0x4b),
33    (0x6c, 0x4c),
34    (0x6d, 0x4d),
35    (0x6e, 0x4e),
36    (0x6f, 0x4f),
37    (0x70, 0x50),
38    (0x71, 0x51),
39    (0x72, 0x52),
40    (0x73, 0x53),
41    (0x74, 0x54),
42    (0x75, 0x55),
43    (0x76, 0x56),
44    (0x77, 0x57),
45    (0x78, 0x58),
46    (0x79, 0x59),
47    (0x7a, 0x5a),
48    (0xb5, 0x39c),
49    (0xe0, 0xc0),
50    (0xe1, 0xc1),
51    (0xe2, 0xc2),
52    (0xe3, 0xc3),
53    (0xe4, 0xc4),
54    (0xe5, 0xc5),
55    (0xe6, 0xc6),
56    (0xe7, 0xc7),
57    (0xe8, 0xc8),
58    (0xe9, 0xc9),
59    (0xea, 0xca),
60    (0xeb, 0xcb),
61    (0xec, 0xcc),
62    (0xed, 0xcd),
63    (0xee, 0xce),
64    (0xef, 0xcf),
65    (0xf0, 0xd0),
66    (0xf1, 0xd1),
67    (0xf2, 0xd2),
68    (0xf3, 0xd3),
69    (0xf4, 0xd4),
70    (0xf5, 0xd5),
71    (0xf6, 0xd6),
72    (0xf8, 0xd8),
73    (0xf9, 0xd9),
74    (0xfa, 0xda),
75    (0xfb, 0xdb),
76    (0xfc, 0xdc),
77    (0xfd, 0xdd),
78    (0xfe, 0xde),
79    (0xff, 0x178),
80    (0x101, 0x100),
81    (0x103, 0x102),
82    (0x105, 0x104),
83    (0x107, 0x106),
84    (0x109, 0x108),
85    (0x10b, 0x10a),
86    (0x10d, 0x10c),
87    (0x10f, 0x10e),
88    (0x111, 0x110),
89    (0x113, 0x112),
90    (0x115, 0x114),
91    (0x117, 0x116),
92    (0x119, 0x118),
93    (0x11b, 0x11a),
94    (0x11d, 0x11c),
95    (0x11f, 0x11e),
96    (0x121, 0x120),
97    (0x123, 0x122),
98    (0x125, 0x124),
99    (0x127, 0x126),
100    (0x129, 0x128),
101    (0x12b, 0x12a),
102    (0x12d, 0x12c),
103    (0x12f, 0x12e),
104    (0x131, 0x49),
105    (0x133, 0x132),
106    (0x135, 0x134),
107    (0x137, 0x136),
108    (0x13a, 0x139),
109    (0x13c, 0x13b),
110    (0x13e, 0x13d),
111    (0x140, 0x13f),
112    (0x142, 0x141),
113    (0x144, 0x143),
114    (0x146, 0x145),
115    (0x148, 0x147),
116    (0x14b, 0x14a),
117    (0x14d, 0x14c),
118    (0x14f, 0x14e),
119    (0x151, 0x150),
120    (0x153, 0x152),
121    (0x155, 0x154),
122    (0x157, 0x156),
123    (0x159, 0x158),
124    (0x15b, 0x15a),
125    (0x15d, 0x15c),
126    (0x15f, 0x15e),
127    (0x161, 0x160),
128    (0x163, 0x162),
129    (0x165, 0x164),
130    (0x167, 0x166),
131    (0x169, 0x168),
132    (0x16b, 0x16a),
133    (0x16d, 0x16c),
134    (0x16f, 0x16e),
135    (0x171, 0x170),
136    (0x173, 0x172),
137    (0x175, 0x174),
138    (0x177, 0x176),
139    (0x17a, 0x179),
140    (0x17c, 0x17b),
141    (0x17e, 0x17d),
142    (0x17f, 0x53),
143    (0x180, 0x243),
144    (0x183, 0x182),
145    (0x185, 0x184),
146    (0x188, 0x187),
147    (0x18c, 0x18b),
148    (0x192, 0x191),
149    (0x195, 0x1f6),
150    (0x199, 0x198),
151    (0x19a, 0x23d),
152    (0x19e, 0x220),
153    (0x1a1, 0x1a0),
154    (0x1a3, 0x1a2),
155    (0x1a5, 0x1a4),
156    (0x1a8, 0x1a7),
157    (0x1ad, 0x1ac),
158    (0x1b0, 0x1af),
159    (0x1b4, 0x1b3),
160    (0x1b6, 0x1b5),
161    (0x1b9, 0x1b8),
162    (0x1bd, 0x1bc),
163    (0x1bf, 0x1f7),
164    (0x1c5, 0x1c4),
165    (0x1c6, 0x1c4),
166    (0x1c8, 0x1c7),
167    (0x1c9, 0x1c7),
168    (0x1cb, 0x1ca),
169    (0x1cc, 0x1ca),
170    (0x1ce, 0x1cd),
171    (0x1d0, 0x1cf),
172    (0x1d2, 0x1d1),
173    (0x1d4, 0x1d3),
174    (0x1d6, 0x1d5),
175    (0x1d8, 0x1d7),
176    (0x1da, 0x1d9),
177    (0x1dc, 0x1db),
178    (0x1dd, 0x18e),
179    (0x1df, 0x1de),
180    (0x1e1, 0x1e0),
181    (0x1e3, 0x1e2),
182    (0x1e5, 0x1e4),
183    (0x1e7, 0x1e6),
184    (0x1e9, 0x1e8),
185    (0x1eb, 0x1ea),
186    (0x1ed, 0x1ec),
187    (0x1ef, 0x1ee),
188    (0x1f2, 0x1f1),
189    (0x1f3, 0x1f1),
190    (0x1f5, 0x1f4),
191    (0x1f9, 0x1f8),
192    (0x1fb, 0x1fa),
193    (0x1fd, 0x1fc),
194    (0x1ff, 0x1fe),
195    (0x201, 0x200),
196    (0x203, 0x202),
197    (0x205, 0x204),
198    (0x207, 0x206),
199    (0x209, 0x208),
200    (0x20b, 0x20a),
201    (0x20d, 0x20c),
202    (0x20f, 0x20e),
203    (0x211, 0x210),
204    (0x213, 0x212),
205    (0x215, 0x214),
206    (0x217, 0x216),
207    (0x219, 0x218),
208    (0x21b, 0x21a),
209    (0x21d, 0x21c),
210    (0x21f, 0x21e),
211    (0x223, 0x222),
212    (0x225, 0x224),
213    (0x227, 0x226),
214    (0x229, 0x228),
215    (0x22b, 0x22a),
216    (0x22d, 0x22c),
217    (0x22f, 0x22e),
218    (0x231, 0x230),
219    (0x233, 0x232),
220    (0x23c, 0x23b),
221    (0x23f, 0x2c7e),
222    (0x240, 0x2c7f),
223    (0x242, 0x241),
224    (0x247, 0x246),
225    (0x249, 0x248),
226    (0x24b, 0x24a),
227    (0x24d, 0x24c),
228    (0x24f, 0x24e),
229    (0x250, 0x2c6f),
230    (0x251, 0x2c6d),
231    (0x252, 0x2c70),
232    (0x253, 0x181),
233    (0x254, 0x186),
234    (0x256, 0x189),
235    (0x257, 0x18a),
236    (0x259, 0x18f),
237    (0x25b, 0x190),
238    (0x25c, 0xa7ab),
239    (0x260, 0x193),
240    (0x261, 0xa7ac),
241    (0x263, 0x194),
242    (0x265, 0xa78d),
243    (0x266, 0xa7aa),
244    (0x268, 0x197),
245    (0x269, 0x196),
246    (0x26a, 0xa7ae),
247    (0x26b, 0x2c62),
248    (0x26c, 0xa7ad),
249    (0x26f, 0x19c),
250    (0x271, 0x2c6e),
251    (0x272, 0x19d),
252    (0x275, 0x19f),
253    (0x27d, 0x2c64),
254    (0x280, 0x1a6),
255    (0x282, 0xa7c5),
256    (0x283, 0x1a9),
257    (0x287, 0xa7b1),
258    (0x288, 0x1ae),
259    (0x289, 0x244),
260    (0x28a, 0x1b1),
261    (0x28b, 0x1b2),
262    (0x28c, 0x245),
263    (0x292, 0x1b7),
264    (0x29d, 0xa7b2),
265    (0x29e, 0xa7b0),
266    (0x345, 0x399),
267    (0x371, 0x370),
268    (0x373, 0x372),
269    (0x377, 0x376),
270    (0x37b, 0x3fd),
271    (0x37c, 0x3fe),
272    (0x37d, 0x3ff),
273    (0x3ac, 0x386),
274    (0x3ad, 0x388),
275    (0x3ae, 0x389),
276    (0x3af, 0x38a),
277    (0x3b1, 0x391),
278    (0x3b2, 0x392),
279    (0x3b3, 0x393),
280    (0x3b4, 0x394),
281    (0x3b5, 0x395),
282    (0x3b6, 0x396),
283    (0x3b7, 0x397),
284    (0x3b8, 0x398),
285    (0x3b9, 0x399),
286    (0x3ba, 0x39a),
287    (0x3bb, 0x39b),
288    (0x3bc, 0x39c),
289    (0x3bd, 0x39d),
290    (0x3be, 0x39e),
291    (0x3bf, 0x39f),
292    (0x3c0, 0x3a0),
293    (0x3c1, 0x3a1),
294    (0x3c2, 0x3a3),
295    (0x3c3, 0x3a3),
296    (0x3c4, 0x3a4),
297    (0x3c5, 0x3a5),
298    (0x3c6, 0x3a6),
299    (0x3c7, 0x3a7),
300    (0x3c8, 0x3a8),
301    (0x3c9, 0x3a9),
302    (0x3ca, 0x3aa),
303    (0x3cb, 0x3ab),
304    (0x3cc, 0x38c),
305    (0x3cd, 0x38e),
306    (0x3ce, 0x38f),
307    (0x3d0, 0x392),
308    (0x3d1, 0x398),
309    (0x3d5, 0x3a6),
310    (0x3d6, 0x3a0),
311    (0x3d7, 0x3cf),
312    (0x3d9, 0x3d8),
313    (0x3db, 0x3da),
314    (0x3dd, 0x3dc),
315    (0x3df, 0x3de),
316    (0x3e1, 0x3e0),
317    (0x3e3, 0x3e2),
318    (0x3e5, 0x3e4),
319    (0x3e7, 0x3e6),
320    (0x3e9, 0x3e8),
321    (0x3eb, 0x3ea),
322    (0x3ed, 0x3ec),
323    (0x3ef, 0x3ee),
324    (0x3f0, 0x39a),
325    (0x3f1, 0x3a1),
326    (0x3f2, 0x3f9),
327    (0x3f3, 0x37f),
328    (0x3f5, 0x395),
329    (0x3f8, 0x3f7),
330    (0x3fb, 0x3fa),
331    (0x430, 0x410),
332    (0x431, 0x411),
333    (0x432, 0x412),
334    (0x433, 0x413),
335    (0x434, 0x414),
336    (0x435, 0x415),
337    (0x436, 0x416),
338    (0x437, 0x417),
339    (0x438, 0x418),
340    (0x439, 0x419),
341    (0x43a, 0x41a),
342    (0x43b, 0x41b),
343    (0x43c, 0x41c),
344    (0x43d, 0x41d),
345    (0x43e, 0x41e),
346    (0x43f, 0x41f),
347    (0x440, 0x420),
348    (0x441, 0x421),
349    (0x442, 0x422),
350    (0x443, 0x423),
351    (0x444, 0x424),
352    (0x445, 0x425),
353    (0x446, 0x426),
354    (0x447, 0x427),
355    (0x448, 0x428),
356    (0x449, 0x429),
357    (0x44a, 0x42a),
358    (0x44b, 0x42b),
359    (0x44c, 0x42c),
360    (0x44d, 0x42d),
361    (0x44e, 0x42e),
362    (0x44f, 0x42f),
363    (0x450, 0x400),
364    (0x451, 0x401),
365    (0x452, 0x402),
366    (0x453, 0x403),
367    (0x454, 0x404),
368    (0x455, 0x405),
369    (0x456, 0x406),
370    (0x457, 0x407),
371    (0x458, 0x408),
372    (0x459, 0x409),
373    (0x45a, 0x40a),
374    (0x45b, 0x40b),
375    (0x45c, 0x40c),
376    (0x45d, 0x40d),
377    (0x45e, 0x40e),
378    (0x45f, 0x40f),
379    (0x461, 0x460),
380    (0x463, 0x462),
381    (0x465, 0x464),
382    (0x467, 0x466),
383    (0x469, 0x468),
384    (0x46b, 0x46a),
385    (0x46d, 0x46c),
386    (0x46f, 0x46e),
387    (0x471, 0x470),
388    (0x473, 0x472),
389    (0x475, 0x474),
390    (0x477, 0x476),
391    (0x479, 0x478),
392    (0x47b, 0x47a),
393    (0x47d, 0x47c),
394    (0x47f, 0x47e),
395    (0x481, 0x480),
396    (0x48b, 0x48a),
397    (0x48d, 0x48c),
398    (0x48f, 0x48e),
399    (0x491, 0x490),
400    (0x493, 0x492),
401    (0x495, 0x494),
402    (0x497, 0x496),
403    (0x499, 0x498),
404    (0x49b, 0x49a),
405    (0x49d, 0x49c),
406    (0x49f, 0x49e),
407    (0x4a1, 0x4a0),
408    (0x4a3, 0x4a2),
409    (0x4a5, 0x4a4),
410    (0x4a7, 0x4a6),
411    (0x4a9, 0x4a8),
412    (0x4ab, 0x4aa),
413    (0x4ad, 0x4ac),
414    (0x4af, 0x4ae),
415    (0x4b1, 0x4b0),
416    (0x4b3, 0x4b2),
417    (0x4b5, 0x4b4),
418    (0x4b7, 0x4b6),
419    (0x4b9, 0x4b8),
420    (0x4bb, 0x4ba),
421    (0x4bd, 0x4bc),
422    (0x4bf, 0x4be),
423    (0x4c2, 0x4c1),
424    (0x4c4, 0x4c3),
425    (0x4c6, 0x4c5),
426    (0x4c8, 0x4c7),
427    (0x4ca, 0x4c9),
428    (0x4cc, 0x4cb),
429    (0x4ce, 0x4cd),
430    (0x4cf, 0x4c0),
431    (0x4d1, 0x4d0),
432    (0x4d3, 0x4d2),
433    (0x4d5, 0x4d4),
434    (0x4d7, 0x4d6),
435    (0x4d9, 0x4d8),
436    (0x4db, 0x4da),
437    (0x4dd, 0x4dc),
438    (0x4df, 0x4de),
439    (0x4e1, 0x4e0),
440    (0x4e3, 0x4e2),
441    (0x4e5, 0x4e4),
442    (0x4e7, 0x4e6),
443    (0x4e9, 0x4e8),
444    (0x4eb, 0x4ea),
445    (0x4ed, 0x4ec),
446    (0x4ef, 0x4ee),
447    (0x4f1, 0x4f0),
448    (0x4f3, 0x4f2),
449    (0x4f5, 0x4f4),
450    (0x4f7, 0x4f6),
451    (0x4f9, 0x4f8),
452    (0x4fb, 0x4fa),
453    (0x4fd, 0x4fc),
454    (0x4ff, 0x4fe),
455    (0x501, 0x500),
456    (0x503, 0x502),
457    (0x505, 0x504),
458    (0x507, 0x506),
459    (0x509, 0x508),
460    (0x50b, 0x50a),
461    (0x50d, 0x50c),
462    (0x50f, 0x50e),
463    (0x511, 0x510),
464    (0x513, 0x512),
465    (0x515, 0x514),
466    (0x517, 0x516),
467    (0x519, 0x518),
468    (0x51b, 0x51a),
469    (0x51d, 0x51c),
470    (0x51f, 0x51e),
471    (0x521, 0x520),
472    (0x523, 0x522),
473    (0x525, 0x524),
474    (0x527, 0x526),
475    (0x529, 0x528),
476    (0x52b, 0x52a),
477    (0x52d, 0x52c),
478    (0x52f, 0x52e),
479    (0x561, 0x531),
480    (0x562, 0x532),
481    (0x563, 0x533),
482    (0x564, 0x534),
483    (0x565, 0x535),
484    (0x566, 0x536),
485    (0x567, 0x537),
486    (0x568, 0x538),
487    (0x569, 0x539),
488    (0x56a, 0x53a),
489    (0x56b, 0x53b),
490    (0x56c, 0x53c),
491    (0x56d, 0x53d),
492    (0x56e, 0x53e),
493    (0x56f, 0x53f),
494    (0x570, 0x540),
495    (0x571, 0x541),
496    (0x572, 0x542),
497    (0x573, 0x543),
498    (0x574, 0x544),
499    (0x575, 0x545),
500    (0x576, 0x546),
501    (0x577, 0x547),
502    (0x578, 0x548),
503    (0x579, 0x549),
504    (0x57a, 0x54a),
505    (0x57b, 0x54b),
506    (0x57c, 0x54c),
507    (0x57d, 0x54d),
508    (0x57e, 0x54e),
509    (0x57f, 0x54f),
510    (0x580, 0x550),
511    (0x581, 0x551),
512    (0x582, 0x552),
513    (0x583, 0x553),
514    (0x584, 0x554),
515    (0x585, 0x555),
516    (0x586, 0x556),
517    (0x10d0, 0x1c90),
518    (0x10d1, 0x1c91),
519    (0x10d2, 0x1c92),
520    (0x10d3, 0x1c93),
521    (0x10d4, 0x1c94),
522    (0x10d5, 0x1c95),
523    (0x10d6, 0x1c96),
524    (0x10d7, 0x1c97),
525    (0x10d8, 0x1c98),
526    (0x10d9, 0x1c99),
527    (0x10da, 0x1c9a),
528    (0x10db, 0x1c9b),
529    (0x10dc, 0x1c9c),
530    (0x10dd, 0x1c9d),
531    (0x10de, 0x1c9e),
532    (0x10df, 0x1c9f),
533    (0x10e0, 0x1ca0),
534    (0x10e1, 0x1ca1),
535    (0x10e2, 0x1ca2),
536    (0x10e3, 0x1ca3),
537    (0x10e4, 0x1ca4),
538    (0x10e5, 0x1ca5),
539    (0x10e6, 0x1ca6),
540    (0x10e7, 0x1ca7),
541    (0x10e8, 0x1ca8),
542    (0x10e9, 0x1ca9),
543    (0x10ea, 0x1caa),
544    (0x10eb, 0x1cab),
545    (0x10ec, 0x1cac),
546    (0x10ed, 0x1cad),
547    (0x10ee, 0x1cae),
548    (0x10ef, 0x1caf),
549    (0x10f0, 0x1cb0),
550    (0x10f1, 0x1cb1),
551    (0x10f2, 0x1cb2),
552    (0x10f3, 0x1cb3),
553    (0x10f4, 0x1cb4),
554    (0x10f5, 0x1cb5),
555    (0x10f6, 0x1cb6),
556    (0x10f7, 0x1cb7),
557    (0x10f8, 0x1cb8),
558    (0x10f9, 0x1cb9),
559    (0x10fa, 0x1cba),
560    (0x10fd, 0x1cbd),
561    (0x10fe, 0x1cbe),
562    (0x10ff, 0x1cbf),
563    (0x13f8, 0x13f0),
564    (0x13f9, 0x13f1),
565    (0x13fa, 0x13f2),
566    (0x13fb, 0x13f3),
567    (0x13fc, 0x13f4),
568    (0x13fd, 0x13f5),
569    (0x1c80, 0x412),
570    (0x1c81, 0x414),
571    (0x1c82, 0x41e),
572    (0x1c83, 0x421),
573    (0x1c84, 0x422),
574    (0x1c85, 0x422),
575    (0x1c86, 0x42a),
576    (0x1c87, 0x462),
577    (0x1c88, 0xa64a),
578    (0x1d79, 0xa77d),
579    (0x1d7d, 0x2c63),
580    (0x1d8e, 0xa7c6),
581    (0x1e01, 0x1e00),
582    (0x1e03, 0x1e02),
583    (0x1e05, 0x1e04),
584    (0x1e07, 0x1e06),
585    (0x1e09, 0x1e08),
586    (0x1e0b, 0x1e0a),
587    (0x1e0d, 0x1e0c),
588    (0x1e0f, 0x1e0e),
589    (0x1e11, 0x1e10),
590    (0x1e13, 0x1e12),
591    (0x1e15, 0x1e14),
592    (0x1e17, 0x1e16),
593    (0x1e19, 0x1e18),
594    (0x1e1b, 0x1e1a),
595    (0x1e1d, 0x1e1c),
596    (0x1e1f, 0x1e1e),
597    (0x1e21, 0x1e20),
598    (0x1e23, 0x1e22),
599    (0x1e25, 0x1e24),
600    (0x1e27, 0x1e26),
601    (0x1e29, 0x1e28),
602    (0x1e2b, 0x1e2a),
603    (0x1e2d, 0x1e2c),
604    (0x1e2f, 0x1e2e),
605    (0x1e31, 0x1e30),
606    (0x1e33, 0x1e32),
607    (0x1e35, 0x1e34),
608    (0x1e37, 0x1e36),
609    (0x1e39, 0x1e38),
610    (0x1e3b, 0x1e3a),
611    (0x1e3d, 0x1e3c),
612    (0x1e3f, 0x1e3e),
613    (0x1e41, 0x1e40),
614    (0x1e43, 0x1e42),
615    (0x1e45, 0x1e44),
616    (0x1e47, 0x1e46),
617    (0x1e49, 0x1e48),
618    (0x1e4b, 0x1e4a),
619    (0x1e4d, 0x1e4c),
620    (0x1e4f, 0x1e4e),
621    (0x1e51, 0x1e50),
622    (0x1e53, 0x1e52),
623    (0x1e55, 0x1e54),
624    (0x1e57, 0x1e56),
625    (0x1e59, 0x1e58),
626    (0x1e5b, 0x1e5a),
627    (0x1e5d, 0x1e5c),
628    (0x1e5f, 0x1e5e),
629    (0x1e61, 0x1e60),
630    (0x1e63, 0x1e62),
631    (0x1e65, 0x1e64),
632    (0x1e67, 0x1e66),
633    (0x1e69, 0x1e68),
634    (0x1e6b, 0x1e6a),
635    (0x1e6d, 0x1e6c),
636    (0x1e6f, 0x1e6e),
637    (0x1e71, 0x1e70),
638    (0x1e73, 0x1e72),
639    (0x1e75, 0x1e74),
640    (0x1e77, 0x1e76),
641    (0x1e79, 0x1e78),
642    (0x1e7b, 0x1e7a),
643    (0x1e7d, 0x1e7c),
644    (0x1e7f, 0x1e7e),
645    (0x1e81, 0x1e80),
646    (0x1e83, 0x1e82),
647    (0x1e85, 0x1e84),
648    (0x1e87, 0x1e86),
649    (0x1e89, 0x1e88),
650    (0x1e8b, 0x1e8a),
651    (0x1e8d, 0x1e8c),
652    (0x1e8f, 0x1e8e),
653    (0x1e91, 0x1e90),
654    (0x1e93, 0x1e92),
655    (0x1e95, 0x1e94),
656    (0x1e9b, 0x1e60),
657    (0x1ea1, 0x1ea0),
658    (0x1ea3, 0x1ea2),
659    (0x1ea5, 0x1ea4),
660    (0x1ea7, 0x1ea6),
661    (0x1ea9, 0x1ea8),
662    (0x1eab, 0x1eaa),
663    (0x1ead, 0x1eac),
664    (0x1eaf, 0x1eae),
665    (0x1eb1, 0x1eb0),
666    (0x1eb3, 0x1eb2),
667    (0x1eb5, 0x1eb4),
668    (0x1eb7, 0x1eb6),
669    (0x1eb9, 0x1eb8),
670    (0x1ebb, 0x1eba),
671    (0x1ebd, 0x1ebc),
672    (0x1ebf, 0x1ebe),
673    (0x1ec1, 0x1ec0),
674    (0x1ec3, 0x1ec2),
675    (0x1ec5, 0x1ec4),
676    (0x1ec7, 0x1ec6),
677    (0x1ec9, 0x1ec8),
678    (0x1ecb, 0x1eca),
679    (0x1ecd, 0x1ecc),
680    (0x1ecf, 0x1ece),
681    (0x1ed1, 0x1ed0),
682    (0x1ed3, 0x1ed2),
683    (0x1ed5, 0x1ed4),
684    (0x1ed7, 0x1ed6),
685    (0x1ed9, 0x1ed8),
686    (0x1edb, 0x1eda),
687    (0x1edd, 0x1edc),
688    (0x1edf, 0x1ede),
689    (0x1ee1, 0x1ee0),
690    (0x1ee3, 0x1ee2),
691    (0x1ee5, 0x1ee4),
692    (0x1ee7, 0x1ee6),
693    (0x1ee9, 0x1ee8),
694    (0x1eeb, 0x1eea),
695    (0x1eed, 0x1eec),
696    (0x1eef, 0x1eee),
697    (0x1ef1, 0x1ef0),
698    (0x1ef3, 0x1ef2),
699    (0x1ef5, 0x1ef4),
700    (0x1ef7, 0x1ef6),
701    (0x1ef9, 0x1ef8),
702    (0x1efb, 0x1efa),
703    (0x1efd, 0x1efc),
704    (0x1eff, 0x1efe),
705    (0x1f00, 0x1f08),
706    (0x1f01, 0x1f09),
707    (0x1f02, 0x1f0a),
708    (0x1f03, 0x1f0b),
709    (0x1f04, 0x1f0c),
710    (0x1f05, 0x1f0d),
711    (0x1f06, 0x1f0e),
712    (0x1f07, 0x1f0f),
713    (0x1f10, 0x1f18),
714    (0x1f11, 0x1f19),
715    (0x1f12, 0x1f1a),
716    (0x1f13, 0x1f1b),
717    (0x1f14, 0x1f1c),
718    (0x1f15, 0x1f1d),
719    (0x1f20, 0x1f28),
720    (0x1f21, 0x1f29),
721    (0x1f22, 0x1f2a),
722    (0x1f23, 0x1f2b),
723    (0x1f24, 0x1f2c),
724    (0x1f25, 0x1f2d),
725    (0x1f26, 0x1f2e),
726    (0x1f27, 0x1f2f),
727    (0x1f30, 0x1f38),
728    (0x1f31, 0x1f39),
729    (0x1f32, 0x1f3a),
730    (0x1f33, 0x1f3b),
731    (0x1f34, 0x1f3c),
732    (0x1f35, 0x1f3d),
733    (0x1f36, 0x1f3e),
734    (0x1f37, 0x1f3f),
735    (0x1f40, 0x1f48),
736    (0x1f41, 0x1f49),
737    (0x1f42, 0x1f4a),
738    (0x1f43, 0x1f4b),
739    (0x1f44, 0x1f4c),
740    (0x1f45, 0x1f4d),
741    (0x1f51, 0x1f59),
742    (0x1f53, 0x1f5b),
743    (0x1f55, 0x1f5d),
744    (0x1f57, 0x1f5f),
745    (0x1f60, 0x1f68),
746    (0x1f61, 0x1f69),
747    (0x1f62, 0x1f6a),
748    (0x1f63, 0x1f6b),
749    (0x1f64, 0x1f6c),
750    (0x1f65, 0x1f6d),
751    (0x1f66, 0x1f6e),
752    (0x1f67, 0x1f6f),
753    (0x1f70, 0x1fba),
754    (0x1f71, 0x1fbb),
755    (0x1f72, 0x1fc8),
756    (0x1f73, 0x1fc9),
757    (0x1f74, 0x1fca),
758    (0x1f75, 0x1fcb),
759    (0x1f76, 0x1fda),
760    (0x1f77, 0x1fdb),
761    (0x1f78, 0x1ff8),
762    (0x1f79, 0x1ff9),
763    (0x1f7a, 0x1fea),
764    (0x1f7b, 0x1feb),
765    (0x1f7c, 0x1ffa),
766    (0x1f7d, 0x1ffb),
767    (0x1f80, 0x1f88),
768    (0x1f81, 0x1f89),
769    (0x1f82, 0x1f8a),
770    (0x1f83, 0x1f8b),
771    (0x1f84, 0x1f8c),
772    (0x1f85, 0x1f8d),
773    (0x1f86, 0x1f8e),
774    (0x1f87, 0x1f8f),
775    (0x1f90, 0x1f98),
776    (0x1f91, 0x1f99),
777    (0x1f92, 0x1f9a),
778    (0x1f93, 0x1f9b),
779    (0x1f94, 0x1f9c),
780    (0x1f95, 0x1f9d),
781    (0x1f96, 0x1f9e),
782    (0x1f97, 0x1f9f),
783    (0x1fa0, 0x1fa8),
784    (0x1fa1, 0x1fa9),
785    (0x1fa2, 0x1faa),
786    (0x1fa3, 0x1fab),
787    (0x1fa4, 0x1fac),
788    (0x1fa5, 0x1fad),
789    (0x1fa6, 0x1fae),
790    (0x1fa7, 0x1faf),
791    (0x1fb0, 0x1fb8),
792    (0x1fb1, 0x1fb9),
793    (0x1fb3, 0x1fbc),
794    (0x1fbe, 0x399),
795    (0x1fc3, 0x1fcc),
796    (0x1fd0, 0x1fd8),
797    (0x1fd1, 0x1fd9),
798    (0x1fe0, 0x1fe8),
799    (0x1fe1, 0x1fe9),
800    (0x1fe5, 0x1fec),
801    (0x1ff3, 0x1ffc),
802    (0x214e, 0x2132),
803    (0x2170, 0x2160),
804    (0x2171, 0x2161),
805    (0x2172, 0x2162),
806    (0x2173, 0x2163),
807    (0x2174, 0x2164),
808    (0x2175, 0x2165),
809    (0x2176, 0x2166),
810    (0x2177, 0x2167),
811    (0x2178, 0x2168),
812    (0x2179, 0x2169),
813    (0x217a, 0x216a),
814    (0x217b, 0x216b),
815    (0x217c, 0x216c),
816    (0x217d, 0x216d),
817    (0x217e, 0x216e),
818    (0x217f, 0x216f),
819    (0x2184, 0x2183),
820    (0x24d0, 0x24b6),
821    (0x24d1, 0x24b7),
822    (0x24d2, 0x24b8),
823    (0x24d3, 0x24b9),
824    (0x24d4, 0x24ba),
825    (0x24d5, 0x24bb),
826    (0x24d6, 0x24bc),
827    (0x24d7, 0x24bd),
828    (0x24d8, 0x24be),
829    (0x24d9, 0x24bf),
830    (0x24da, 0x24c0),
831    (0x24db, 0x24c1),
832    (0x24dc, 0x24c2),
833    (0x24dd, 0x24c3),
834    (0x24de, 0x24c4),
835    (0x24df, 0x24c5),
836    (0x24e0, 0x24c6),
837    (0x24e1, 0x24c7),
838    (0x24e2, 0x24c8),
839    (0x24e3, 0x24c9),
840    (0x24e4, 0x24ca),
841    (0x24e5, 0x24cb),
842    (0x24e6, 0x24cc),
843    (0x24e7, 0x24cd),
844    (0x24e8, 0x24ce),
845    (0x24e9, 0x24cf),
846    (0x2c30, 0x2c00),
847    (0x2c31, 0x2c01),
848    (0x2c32, 0x2c02),
849    (0x2c33, 0x2c03),
850    (0x2c34, 0x2c04),
851    (0x2c35, 0x2c05),
852    (0x2c36, 0x2c06),
853    (0x2c37, 0x2c07),
854    (0x2c38, 0x2c08),
855    (0x2c39, 0x2c09),
856    (0x2c3a, 0x2c0a),
857    (0x2c3b, 0x2c0b),
858    (0x2c3c, 0x2c0c),
859    (0x2c3d, 0x2c0d),
860    (0x2c3e, 0x2c0e),
861    (0x2c3f, 0x2c0f),
862    (0x2c40, 0x2c10),
863    (0x2c41, 0x2c11),
864    (0x2c42, 0x2c12),
865    (0x2c43, 0x2c13),
866    (0x2c44, 0x2c14),
867    (0x2c45, 0x2c15),
868    (0x2c46, 0x2c16),
869    (0x2c47, 0x2c17),
870    (0x2c48, 0x2c18),
871    (0x2c49, 0x2c19),
872    (0x2c4a, 0x2c1a),
873    (0x2c4b, 0x2c1b),
874    (0x2c4c, 0x2c1c),
875    (0x2c4d, 0x2c1d),
876    (0x2c4e, 0x2c1e),
877    (0x2c4f, 0x2c1f),
878    (0x2c50, 0x2c20),
879    (0x2c51, 0x2c21),
880    (0x2c52, 0x2c22),
881    (0x2c53, 0x2c23),
882    (0x2c54, 0x2c24),
883    (0x2c55, 0x2c25),
884    (0x2c56, 0x2c26),
885    (0x2c57, 0x2c27),
886    (0x2c58, 0x2c28),
887    (0x2c59, 0x2c29),
888    (0x2c5a, 0x2c2a),
889    (0x2c5b, 0x2c2b),
890    (0x2c5c, 0x2c2c),
891    (0x2c5d, 0x2c2d),
892    (0x2c5e, 0x2c2e),
893    (0x2c61, 0x2c60),
894    (0x2c65, 0x23a),
895    (0x2c66, 0x23e),
896    (0x2c68, 0x2c67),
897    (0x2c6a, 0x2c69),
898    (0x2c6c, 0x2c6b),
899    (0x2c73, 0x2c72),
900    (0x2c76, 0x2c75),
901    (0x2c81, 0x2c80),
902    (0x2c83, 0x2c82),
903    (0x2c85, 0x2c84),
904    (0x2c87, 0x2c86),
905    (0x2c89, 0x2c88),
906    (0x2c8b, 0x2c8a),
907    (0x2c8d, 0x2c8c),
908    (0x2c8f, 0x2c8e),
909    (0x2c91, 0x2c90),
910    (0x2c93, 0x2c92),
911    (0x2c95, 0x2c94),
912    (0x2c97, 0x2c96),
913    (0x2c99, 0x2c98),
914    (0x2c9b, 0x2c9a),
915    (0x2c9d, 0x2c9c),
916    (0x2c9f, 0x2c9e),
917    (0x2ca1, 0x2ca0),
918    (0x2ca3, 0x2ca2),
919    (0x2ca5, 0x2ca4),
920    (0x2ca7, 0x2ca6),
921    (0x2ca9, 0x2ca8),
922    (0x2cab, 0x2caa),
923    (0x2cad, 0x2cac),
924    (0x2caf, 0x2cae),
925    (0x2cb1, 0x2cb0),
926    (0x2cb3, 0x2cb2),
927    (0x2cb5, 0x2cb4),
928    (0x2cb7, 0x2cb6),
929    (0x2cb9, 0x2cb8),
930    (0x2cbb, 0x2cba),
931    (0x2cbd, 0x2cbc),
932    (0x2cbf, 0x2cbe),
933    (0x2cc1, 0x2cc0),
934    (0x2cc3, 0x2cc2),
935    (0x2cc5, 0x2cc4),
936    (0x2cc7, 0x2cc6),
937    (0x2cc9, 0x2cc8),
938    (0x2ccb, 0x2cca),
939    (0x2ccd, 0x2ccc),
940    (0x2ccf, 0x2cce),
941    (0x2cd1, 0x2cd0),
942    (0x2cd3, 0x2cd2),
943    (0x2cd5, 0x2cd4),
944    (0x2cd7, 0x2cd6),
945    (0x2cd9, 0x2cd8),
946    (0x2cdb, 0x2cda),
947    (0x2cdd, 0x2cdc),
948    (0x2cdf, 0x2cde),
949    (0x2ce1, 0x2ce0),
950    (0x2ce3, 0x2ce2),
951    (0x2cec, 0x2ceb),
952    (0x2cee, 0x2ced),
953    (0x2cf3, 0x2cf2),
954    (0x2d00, 0x10a0),
955    (0x2d01, 0x10a1),
956    (0x2d02, 0x10a2),
957    (0x2d03, 0x10a3),
958    (0x2d04, 0x10a4),
959    (0x2d05, 0x10a5),
960    (0x2d06, 0x10a6),
961    (0x2d07, 0x10a7),
962    (0x2d08, 0x10a8),
963    (0x2d09, 0x10a9),
964    (0x2d0a, 0x10aa),
965    (0x2d0b, 0x10ab),
966    (0x2d0c, 0x10ac),
967    (0x2d0d, 0x10ad),
968    (0x2d0e, 0x10ae),
969    (0x2d0f, 0x10af),
970    (0x2d10, 0x10b0),
971    (0x2d11, 0x10b1),
972    (0x2d12, 0x10b2),
973    (0x2d13, 0x10b3),
974    (0x2d14, 0x10b4),
975    (0x2d15, 0x10b5),
976    (0x2d16, 0x10b6),
977    (0x2d17, 0x10b7),
978    (0x2d18, 0x10b8),
979    (0x2d19, 0x10b9),
980    (0x2d1a, 0x10ba),
981    (0x2d1b, 0x10bb),
982    (0x2d1c, 0x10bc),
983    (0x2d1d, 0x10bd),
984    (0x2d1e, 0x10be),
985    (0x2d1f, 0x10bf),
986    (0x2d20, 0x10c0),
987    (0x2d21, 0x10c1),
988    (0x2d22, 0x10c2),
989    (0x2d23, 0x10c3),
990    (0x2d24, 0x10c4),
991    (0x2d25, 0x10c5),
992    (0x2d27, 0x10c7),
993    (0x2d2d, 0x10cd),
994    (0xa641, 0xa640),
995    (0xa643, 0xa642),
996    (0xa645, 0xa644),
997    (0xa647, 0xa646),
998    (0xa649, 0xa648),
999    (0xa64b, 0xa64a),
1000    (0xa64d, 0xa64c),
1001    (0xa64f, 0xa64e),
1002    (0xa651, 0xa650),
1003    (0xa653, 0xa652),
1004    (0xa655, 0xa654),
1005    (0xa657, 0xa656),
1006    (0xa659, 0xa658),
1007    (0xa65b, 0xa65a),
1008    (0xa65d, 0xa65c),
1009    (0xa65f, 0xa65e),
1010    (0xa661, 0xa660),
1011    (0xa663, 0xa662),
1012    (0xa665, 0xa664),
1013    (0xa667, 0xa666),
1014    (0xa669, 0xa668),
1015    (0xa66b, 0xa66a),
1016    (0xa66d, 0xa66c),
1017    (0xa681, 0xa680),
1018    (0xa683, 0xa682),
1019    (0xa685, 0xa684),
1020    (0xa687, 0xa686),
1021    (0xa689, 0xa688),
1022    (0xa68b, 0xa68a),
1023    (0xa68d, 0xa68c),
1024    (0xa68f, 0xa68e),
1025    (0xa691, 0xa690),
1026    (0xa693, 0xa692),
1027    (0xa695, 0xa694),
1028    (0xa697, 0xa696),
1029    (0xa699, 0xa698),
1030    (0xa69b, 0xa69a),
1031    (0xa723, 0xa722),
1032    (0xa725, 0xa724),
1033    (0xa727, 0xa726),
1034    (0xa729, 0xa728),
1035    (0xa72b, 0xa72a),
1036    (0xa72d, 0xa72c),
1037    (0xa72f, 0xa72e),
1038    (0xa733, 0xa732),
1039    (0xa735, 0xa734),
1040    (0xa737, 0xa736),
1041    (0xa739, 0xa738),
1042    (0xa73b, 0xa73a),
1043    (0xa73d, 0xa73c),
1044    (0xa73f, 0xa73e),
1045    (0xa741, 0xa740),
1046    (0xa743, 0xa742),
1047    (0xa745, 0xa744),
1048    (0xa747, 0xa746),
1049    (0xa749, 0xa748),
1050    (0xa74b, 0xa74a),
1051    (0xa74d, 0xa74c),
1052    (0xa74f, 0xa74e),
1053    (0xa751, 0xa750),
1054    (0xa753, 0xa752),
1055    (0xa755, 0xa754),
1056    (0xa757, 0xa756),
1057    (0xa759, 0xa758),
1058    (0xa75b, 0xa75a),
1059    (0xa75d, 0xa75c),
1060    (0xa75f, 0xa75e),
1061    (0xa761, 0xa760),
1062    (0xa763, 0xa762),
1063    (0xa765, 0xa764),
1064    (0xa767, 0xa766),
1065    (0xa769, 0xa768),
1066    (0xa76b, 0xa76a),
1067    (0xa76d, 0xa76c),
1068    (0xa76f, 0xa76e),
1069    (0xa77a, 0xa779),
1070    (0xa77c, 0xa77b),
1071    (0xa77f, 0xa77e),
1072    (0xa781, 0xa780),
1073    (0xa783, 0xa782),
1074    (0xa785, 0xa784),
1075    (0xa787, 0xa786),
1076    (0xa78c, 0xa78b),
1077    (0xa791, 0xa790),
1078    (0xa793, 0xa792),
1079    (0xa794, 0xa7c4),
1080    (0xa797, 0xa796),
1081    (0xa799, 0xa798),
1082    (0xa79b, 0xa79a),
1083    (0xa79d, 0xa79c),
1084    (0xa79f, 0xa79e),
1085    (0xa7a1, 0xa7a0),
1086    (0xa7a3, 0xa7a2),
1087    (0xa7a5, 0xa7a4),
1088    (0xa7a7, 0xa7a6),
1089    (0xa7a9, 0xa7a8),
1090    (0xa7b5, 0xa7b4),
1091    (0xa7b7, 0xa7b6),
1092    (0xa7b9, 0xa7b8),
1093    (0xa7bb, 0xa7ba),
1094    (0xa7bd, 0xa7bc),
1095    (0xa7bf, 0xa7be),
1096    (0xa7c3, 0xa7c2),
1097    (0xa7c8, 0xa7c7),
1098    (0xa7ca, 0xa7c9),
1099    (0xa7f6, 0xa7f5),
1100    (0xab53, 0xa7b3),
1101    (0xab70, 0x13a0),
1102    (0xab71, 0x13a1),
1103    (0xab72, 0x13a2),
1104    (0xab73, 0x13a3),
1105    (0xab74, 0x13a4),
1106    (0xab75, 0x13a5),
1107    (0xab76, 0x13a6),
1108    (0xab77, 0x13a7),
1109    (0xab78, 0x13a8),
1110    (0xab79, 0x13a9),
1111    (0xab7a, 0x13aa),
1112    (0xab7b, 0x13ab),
1113    (0xab7c, 0x13ac),
1114    (0xab7d, 0x13ad),
1115    (0xab7e, 0x13ae),
1116    (0xab7f, 0x13af),
1117    (0xab80, 0x13b0),
1118    (0xab81, 0x13b1),
1119    (0xab82, 0x13b2),
1120    (0xab83, 0x13b3),
1121    (0xab84, 0x13b4),
1122    (0xab85, 0x13b5),
1123    (0xab86, 0x13b6),
1124    (0xab87, 0x13b7),
1125    (0xab88, 0x13b8),
1126    (0xab89, 0x13b9),
1127    (0xab8a, 0x13ba),
1128    (0xab8b, 0x13bb),
1129    (0xab8c, 0x13bc),
1130    (0xab8d, 0x13bd),
1131    (0xab8e, 0x13be),
1132    (0xab8f, 0x13bf),
1133    (0xab90, 0x13c0),
1134    (0xab91, 0x13c1),
1135    (0xab92, 0x13c2),
1136    (0xab93, 0x13c3),
1137    (0xab94, 0x13c4),
1138    (0xab95, 0x13c5),
1139    (0xab96, 0x13c6),
1140    (0xab97, 0x13c7),
1141    (0xab98, 0x13c8),
1142    (0xab99, 0x13c9),
1143    (0xab9a, 0x13ca),
1144    (0xab9b, 0x13cb),
1145    (0xab9c, 0x13cc),
1146    (0xab9d, 0x13cd),
1147    (0xab9e, 0x13ce),
1148    (0xab9f, 0x13cf),
1149    (0xaba0, 0x13d0),
1150    (0xaba1, 0x13d1),
1151    (0xaba2, 0x13d2),
1152    (0xaba3, 0x13d3),
1153    (0xaba4, 0x13d4),
1154    (0xaba5, 0x13d5),
1155    (0xaba6, 0x13d6),
1156    (0xaba7, 0x13d7),
1157    (0xaba8, 0x13d8),
1158    (0xaba9, 0x13d9),
1159    (0xabaa, 0x13da),
1160    (0xabab, 0x13db),
1161    (0xabac, 0x13dc),
1162    (0xabad, 0x13dd),
1163    (0xabae, 0x13de),
1164    (0xabaf, 0x13df),
1165    (0xabb0, 0x13e0),
1166    (0xabb1, 0x13e1),
1167    (0xabb2, 0x13e2),
1168    (0xabb3, 0x13e3),
1169    (0xabb4, 0x13e4),
1170    (0xabb5, 0x13e5),
1171    (0xabb6, 0x13e6),
1172    (0xabb7, 0x13e7),
1173    (0xabb8, 0x13e8),
1174    (0xabb9, 0x13e9),
1175    (0xabba, 0x13ea),
1176    (0xabbb, 0x13eb),
1177    (0xabbc, 0x13ec),
1178    (0xabbd, 0x13ed),
1179    (0xabbe, 0x13ee),
1180    (0xabbf, 0x13ef),
1181    (0xff41, 0xff21),
1182    (0xff42, 0xff22),
1183    (0xff43, 0xff23),
1184    (0xff44, 0xff24),
1185    (0xff45, 0xff25),
1186    (0xff46, 0xff26),
1187    (0xff47, 0xff27),
1188    (0xff48, 0xff28),
1189    (0xff49, 0xff29),
1190    (0xff4a, 0xff2a),
1191    (0xff4b, 0xff2b),
1192    (0xff4c, 0xff2c),
1193    (0xff4d, 0xff2d),
1194    (0xff4e, 0xff2e),
1195    (0xff4f, 0xff2f),
1196    (0xff50, 0xff30),
1197    (0xff51, 0xff31),
1198    (0xff52, 0xff32),
1199    (0xff53, 0xff33),
1200    (0xff54, 0xff34),
1201    (0xff55, 0xff35),
1202    (0xff56, 0xff36),
1203    (0xff57, 0xff37),
1204    (0xff58, 0xff38),
1205    (0xff59, 0xff39),
1206    (0xff5a, 0xff3a),
1207];
1208
1209fn utf16_code_unit_to_uppercase(unit: u16) -> u16 {
1210    match BMP_UPPERCASE_TABLE.binary_search_by(|&(key, _)| key.cmp(&unit)) {
1211        Ok(index) => BMP_UPPERCASE_TABLE[index].1,
1212        Err(_) => unit,
1213    }
1214}
1215
1216/// Zero-copy representation of a key name or value name string stored in hive data.
1217/// Can be either in Latin1 (ISO-8859-1) or UTF-16 (Little-Endian).
1218///
1219/// This allows to work with the string without performing any allocations or conversions.
1220/// If the `alloc` feature is enabled, [`to_string_checked`](NtHiveNameString::to_string_checked) and
1221/// [`to_string_lossy`](NtHiveNameString::to_string_lossy) can be used to to retrieve a `String`.
1222#[derive(Clone, Debug, Eq)]
1223pub enum NtHiveNameString<'h> {
1224    /// A byte stream where each byte is a single character of the Latin1 (ISO-8859-1)
1225    /// character set.
1226    /// Each byte can simply be casted to a [`prim@char`] (as Unicode is ordered the same as Latin1).
1227    Latin1(&'h [u8]),
1228    /// A byte stream where every two bytes make up a UTF-16 code point in little-endian order.
1229    /// Use [`u16::from_le_bytes`] and [`char::decode_utf16`] if you want to get a stream of [`prim@char`]s.
1230    Utf16LE(&'h [u8]),
1231}
1232
1233impl<'h> NtHiveNameString<'h> {
1234    fn cmp_iter<TI, OI>(mut this_iter: TI, mut other_iter: OI) -> Ordering
1235    where
1236        TI: Iterator<Item = u16>,
1237        OI: Iterator<Item = u16>,
1238    {
1239        loop {
1240            match (this_iter.next(), other_iter.next()) {
1241                (Some(this_code_unit), Some(other_code_unit)) => {
1242                    // We have two UTF-16 code units to compare.
1243                    let this_upper = utf16_code_unit_to_uppercase(this_code_unit);
1244                    let other_upper = utf16_code_unit_to_uppercase(other_code_unit);
1245
1246                    if this_upper != other_upper {
1247                        return this_upper.cmp(&other_upper);
1248                    }
1249                }
1250                (Some(_), None) => {
1251                    // `this_iter` is longer than `other_iter` but otherwise equal.
1252                    return Ordering::Greater;
1253                }
1254                (None, Some(_)) => {
1255                    // `other_iter` is longer than `this_iter` but otherwise equal.
1256                    return Ordering::Less;
1257                }
1258                (None, None) => {
1259                    // We made it to the end of both strings, so they must be equal.
1260                    return Ordering::Equal;
1261                }
1262            }
1263        }
1264    }
1265
1266    fn cmp_self_and_str(lhs: &Self, rhs: &str) -> Ordering {
1267        let rhs_iter = rhs.encode_utf16();
1268
1269        match lhs {
1270            Self::Latin1(_) => Self::cmp_iter(lhs.latin1_iter(), rhs_iter),
1271            Self::Utf16LE(_) => Self::cmp_iter(lhs.utf16le_iter(), rhs_iter),
1272        }
1273    }
1274
1275    fn cmp_str_and_self(lhs: &str, rhs: &Self) -> Ordering {
1276        let lhs_iter = lhs.encode_utf16();
1277
1278        match rhs {
1279            Self::Latin1(_) => Self::cmp_iter(lhs_iter, rhs.latin1_iter()),
1280            Self::Utf16LE(_) => Self::cmp_iter(lhs_iter, rhs.utf16le_iter()),
1281        }
1282    }
1283
1284    fn latin1_iter(&'h self) -> impl Iterator<Item = u16> + 'h {
1285        match self {
1286            Self::Latin1(bytes) => bytes.iter().map(|byte| *byte as u16),
1287            Self::Utf16LE(_) => panic!("Called latin1_iter for Utf16LE"),
1288        }
1289    }
1290
1291    fn utf16le_iter(&'h self) -> impl Iterator<Item = u16> + 'h {
1292        match self {
1293            Self::Latin1(_) => panic!("Called utf16le_iter for Latin1"),
1294            Self::Utf16LE(bytes) => bytes
1295                .chunks_exact(2)
1296                .map(|two_bytes| u16::from_le_bytes(two_bytes.try_into().unwrap())),
1297        }
1298    }
1299
1300    /// Returns `true` if `self` has a length of zero bytes.
1301    pub const fn is_empty(&self) -> bool {
1302        self.len() == 0
1303    }
1304
1305    /// Returns the length of `self`.
1306    ///
1307    /// This length is in bytes, not characters! In other words,
1308    /// it may not be what a human considers the length of the string.
1309    pub const fn len(&self) -> usize {
1310        match self {
1311            Self::Latin1(bytes) => bytes.len(),
1312            Self::Utf16LE(bytes) => bytes.len(),
1313        }
1314    }
1315
1316    /// Attempts to convert `self` to an owned `String`.
1317    /// Returns `Some(String)` if all characters could be converted successfully or `None` if a decoding error occurred.
1318    #[cfg(feature = "alloc")]
1319    pub fn to_string_checked(&self) -> Option<String> {
1320        match self {
1321            Self::Latin1(bytes) => {
1322                let string = bytes.iter().map(|byte| *byte as char).collect();
1323                Some(string)
1324            }
1325            Self::Utf16LE(_) => char::decode_utf16(self.utf16le_iter())
1326                .map(|x| x.ok())
1327                .collect::<Option<String>>(),
1328        }
1329    }
1330
1331    /// Converts `self` to an owned `String`, replacing invalid data with the replacement character (U+FFFD).
1332    #[cfg(feature = "alloc")]
1333    pub fn to_string_lossy(&self) -> String {
1334        match self {
1335            Self::Latin1(bytes) => bytes.iter().map(|byte| *byte as char).collect(),
1336            Self::Utf16LE(_) => char::decode_utf16(self.utf16le_iter())
1337                .map(|x| x.unwrap_or(char::REPLACEMENT_CHARACTER))
1338                .collect(),
1339        }
1340    }
1341}
1342
1343impl fmt::Display for NtHiveNameString<'_> {
1344    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1345        match self {
1346            Self::Latin1(bytes) => {
1347                for byte in bytes.iter() {
1348                    let single_char = *byte as char;
1349                    single_char.fmt(f)?;
1350                }
1351            }
1352            Self::Utf16LE(_) => {
1353                let utf16_iter = char::decode_utf16(self.utf16le_iter())
1354                    .map(|x| x.unwrap_or(char::REPLACEMENT_CHARACTER));
1355
1356                for single_char in utf16_iter {
1357                    single_char.fmt(f)?;
1358                }
1359            }
1360        }
1361
1362        Ok(())
1363    }
1364}
1365
1366impl Ord for NtHiveNameString<'_> {
1367    fn cmp(&self, other: &Self) -> Ordering {
1368        match (self, other) {
1369            (Self::Latin1(_), Self::Latin1(_)) => {
1370                Self::cmp_iter(self.latin1_iter(), other.latin1_iter())
1371            }
1372            (Self::Latin1(_), Self::Utf16LE(_)) => {
1373                Self::cmp_iter(self.latin1_iter(), other.utf16le_iter())
1374            }
1375            (Self::Utf16LE(_), Self::Latin1(_)) => {
1376                Self::cmp_iter(self.utf16le_iter(), other.latin1_iter())
1377            }
1378            (Self::Utf16LE(_), Self::Utf16LE(_)) => {
1379                Self::cmp_iter(self.utf16le_iter(), other.utf16le_iter())
1380            }
1381        }
1382    }
1383}
1384
1385impl PartialEq for NtHiveNameString<'_> {
1386    /// Checks that two strings are a case-insensitive match
1387    /// (according to Windows' definition of case-insensitivity, which only considers the
1388    /// Unicode Basic Multilingual Plane).
1389    fn eq(&self, other: &Self) -> bool {
1390        self.cmp(other) == Ordering::Equal
1391    }
1392}
1393
1394impl PartialEq<str> for NtHiveNameString<'_> {
1395    fn eq(&self, other: &str) -> bool {
1396        NtHiveNameString::cmp_self_and_str(self, other) == Ordering::Equal
1397    }
1398}
1399
1400impl<'h> PartialEq<NtHiveNameString<'h>> for str {
1401    fn eq(&self, other: &NtHiveNameString<'h>) -> bool {
1402        NtHiveNameString::cmp_str_and_self(self, other) == Ordering::Equal
1403    }
1404}
1405
1406impl PartialEq<&str> for NtHiveNameString<'_> {
1407    fn eq(&self, other: &&str) -> bool {
1408        NtHiveNameString::cmp_self_and_str(self, other) == Ordering::Equal
1409    }
1410}
1411
1412impl<'h> PartialEq<NtHiveNameString<'h>> for &str {
1413    fn eq(&self, other: &NtHiveNameString<'h>) -> bool {
1414        NtHiveNameString::cmp_str_and_self(self, other) == Ordering::Equal
1415    }
1416}
1417
1418impl PartialOrd for NtHiveNameString<'_> {
1419    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1420        Some(self.cmp(other))
1421    }
1422}
1423
1424impl PartialOrd<str> for NtHiveNameString<'_> {
1425    fn partial_cmp(&self, other: &str) -> Option<Ordering> {
1426        Some(NtHiveNameString::cmp_self_and_str(self, other))
1427    }
1428}
1429
1430impl<'h> PartialOrd<NtHiveNameString<'h>> for str {
1431    fn partial_cmp(&self, other: &NtHiveNameString<'h>) -> Option<Ordering> {
1432        Some(NtHiveNameString::cmp_str_and_self(self, other))
1433    }
1434}
1435
1436impl PartialOrd<&str> for NtHiveNameString<'_> {
1437    fn partial_cmp(&self, other: &&str) -> Option<Ordering> {
1438        Some(NtHiveNameString::cmp_self_and_str(self, other))
1439    }
1440}
1441
1442impl<'h> PartialOrd<NtHiveNameString<'h>> for &str {
1443    fn partial_cmp(&self, other: &NtHiveNameString<'h>) -> Option<Ordering> {
1444        Some(NtHiveNameString::cmp_str_and_self(self, other))
1445    }
1446}
1447
1448#[cfg(test)]
1449mod tests {
1450    use super::*;
1451
1452    #[test]
1453    fn test_eq() {
1454        assert_eq!(NtHiveNameString::Latin1(b"Hello"), "Hello");
1455        assert_eq!(
1456            NtHiveNameString::Utf16LE(&[b'H', 0, b'e', 0, b'l', 0, b'l', 0, b'o', 0]),
1457            "Hello"
1458        );
1459        assert_eq!(NtHiveNameString::Latin1(b"Hello"), "hello");
1460        assert_eq!(
1461            NtHiveNameString::Utf16LE(&[b'H', 0, b'e', 0, b'l', 0, b'l', 0, b'o', 0]),
1462            "hello"
1463        );
1464        assert_eq!(NtHiveNameString::Latin1(b"Hell\xD6"), "hellö");
1465        assert_ne!(NtHiveNameString::Latin1(b"Hello"), "Hell");
1466        assert_ne!(
1467            NtHiveNameString::Utf16LE(&[b'H', 0, b'e', 0, b'l', 0, b'l', 0, b'o', 0]),
1468            "Hell"
1469        );
1470
1471        // Characters in the Basic Multilingual Plane are compared case-insensitively,
1472        // others are not.
1473        let full_width_upper_a = "\u{FF21}"
1474            .encode_utf16()
1475            .flat_map(|utf16_code_point| utf16_code_point.to_le_bytes().to_vec())
1476            .collect::<Vec<u8>>();
1477        let full_width_lower_a = "\u{FF41}"
1478            .encode_utf16()
1479            .flat_map(|utf16_code_point| utf16_code_point.to_le_bytes().to_vec())
1480            .collect::<Vec<u8>>();
1481        assert_eq!(
1482            NtHiveNameString::Utf16LE(&full_width_upper_a),
1483            NtHiveNameString::Utf16LE(&full_width_lower_a)
1484        );
1485
1486        let deseret_upper_h = "\u{10410}"
1487            .encode_utf16()
1488            .flat_map(|utf16_code_point| utf16_code_point.to_le_bytes().to_vec())
1489            .collect::<Vec<u8>>();
1490        let deseret_lower_h = "\u{10438}"
1491            .encode_utf16()
1492            .flat_map(|utf16_code_point| utf16_code_point.to_le_bytes().to_vec())
1493            .collect::<Vec<u8>>();
1494        assert_ne!(
1495            NtHiveNameString::Utf16LE(&deseret_upper_h),
1496            NtHiveNameString::Utf16LE(&deseret_lower_h)
1497        );
1498    }
1499
1500    #[test]
1501    fn test_is_empty() {
1502        assert!(NtHiveNameString::Latin1(b"").is_empty());
1503        assert!(NtHiveNameString::Utf16LE(&[]).is_empty());
1504        assert!(!NtHiveNameString::Latin1(b"Hello").is_empty());
1505        assert!(
1506            !NtHiveNameString::Utf16LE(&[b'H', 0, b'e', 0, b'l', 0, b'l', 0, b'o', 0]).is_empty()
1507        );
1508    }
1509
1510    #[test]
1511    fn test_len() {
1512        assert_eq!(NtHiveNameString::Latin1(b"Hello").len(), 5);
1513        assert_eq!(
1514            NtHiveNameString::Utf16LE(&[b'H', 0, b'e', 0, b'l', 0, b'l', 0, b'o', 0]).len(),
1515            10
1516        );
1517    }
1518
1519    #[test]
1520    fn test_ord() {
1521        assert!(NtHiveNameString::Latin1(b"a") < "b");
1522        assert!("b" > NtHiveNameString::Latin1(b"a"));
1523
1524        assert!(NtHiveNameString::Latin1(b"a") == NtHiveNameString::Latin1(b"a"));
1525        assert!(NtHiveNameString::Latin1(b"a") < NtHiveNameString::Latin1(b"aa"));
1526        assert!(NtHiveNameString::Latin1(b"aa") > NtHiveNameString::Latin1(b"a"));
1527        assert!(NtHiveNameString::Latin1(b"a") < NtHiveNameString::Latin1(b"b"));
1528
1529        // Even though Unicode character 0x10331 (Gothic Letter Bairkan) has a higher
1530        // code point than Unicode character 0xFF21 (Full-Width Latin Capital Letter A), Windows
1531        // hives order name strings by their UTF-16 representation.
1532        // Hence, 0x10331 is encoded as 0xD800 0xDF31 and comes before 0xFF21
1533        // (which is the same in UTF-16).
1534        let full_width_a = "\u{FF21}"
1535            .encode_utf16()
1536            .flat_map(|utf16_code_point| utf16_code_point.to_le_bytes().to_vec())
1537            .collect::<Vec<u8>>();
1538        let gothic_bairkan = "\u{10331}"
1539            .encode_utf16()
1540            .flat_map(|utf16_code_point| utf16_code_point.to_le_bytes().to_vec())
1541            .collect::<Vec<u8>>();
1542        assert!(
1543            NtHiveNameString::Utf16LE(&gothic_bairkan) < NtHiveNameString::Utf16LE(&full_width_a)
1544        );
1545    }
1546}