[RXCE]
[reactos.git] / reactos / sdk / lib / rtl / nls.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/nls.c
5 * PURPOSE: National Language Support (NLS) functions
6 * PROGRAMMERS: Emanuele Aliberti
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #include <rtl.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* GLOBALS *******************************************************************/
17
18 PUSHORT NlsUnicodeUpcaseTable = NULL;
19 PUSHORT NlsUnicodeLowercaseTable = NULL;
20
21 USHORT NlsAnsiCodePage = 0; /* exported */
22 BOOLEAN NlsMbCodePageTag = FALSE; /* exported */
23 PUSHORT NlsAnsiToUnicodeTable = NULL;
24 PCHAR NlsUnicodeToAnsiTable = NULL;
25 PUSHORT NlsUnicodeToMbAnsiTable = NULL;
26 PUSHORT NlsLeadByteInfo = NULL; /* exported */
27
28 USHORT NlsOemCodePage = 0;
29 BOOLEAN NlsMbOemCodePageTag = FALSE; /* exported */
30 PUSHORT NlsOemToUnicodeTable = NULL;
31 PCHAR NlsUnicodeToOemTable = NULL;
32 PUSHORT NlsUnicodeToMbOemTable = NULL;
33 PUSHORT NlsOemLeadByteInfo = NULL; /* exported */
34
35 USHORT NlsOemDefaultChar = '\0';
36 USHORT NlsUnicodeDefaultChar = 0;
37
38
39 /* FUNCTIONS *****************************************************************/
40
41 /*
42 * @unimplemented
43 */
44 NTSTATUS NTAPI
45 RtlCustomCPToUnicodeN(IN PCPTABLEINFO CustomCP,
46 OUT PWCHAR UnicodeString,
47 IN ULONG UnicodeSize,
48 OUT PULONG ResultSize OPTIONAL,
49 IN PCHAR CustomString,
50 IN ULONG CustomSize)
51 {
52 ULONG Size = 0;
53 ULONG i;
54
55 PAGED_CODE_RTL();
56
57 if (!CustomCP->DBCSCodePage)
58 {
59 /* single-byte code page */
60 if (CustomSize > (UnicodeSize / sizeof(WCHAR)))
61 Size = UnicodeSize / sizeof(WCHAR);
62 else
63 Size = CustomSize;
64
65 if (ResultSize)
66 *ResultSize = Size * sizeof(WCHAR);
67
68 for (i = 0; i < Size; i++)
69 {
70 *UnicodeString = CustomCP->MultiByteTable[(UCHAR)*CustomString];
71 UnicodeString++;
72 CustomString++;
73 }
74 }
75 else
76 {
77 /* multi-byte code page */
78 /* FIXME */
79 ASSERT(FALSE);
80 }
81
82 return STATUS_SUCCESS;
83 }
84
85 /*
86 * @implemented
87 */
88 WCHAR NTAPI
89 RtlpDowncaseUnicodeChar(IN WCHAR Source)
90 {
91 USHORT Offset;
92
93 PAGED_CODE_RTL();
94
95 if (Source < L'A')
96 return Source;
97
98 if (Source <= L'Z')
99 return Source + (L'a' - L'A');
100
101 if (Source < 0x80)
102 return Source;
103
104 Offset = ((USHORT)Source >> 8);
105 DPRINT("Offset: %hx\n", Offset);
106
107 Offset = NlsUnicodeLowercaseTable[Offset];
108 DPRINT("Offset: %hx\n", Offset);
109
110 Offset += (((USHORT)Source & 0x00F0) >> 4);
111 DPRINT("Offset: %hx\n", Offset);
112
113 Offset = NlsUnicodeLowercaseTable[Offset];
114 DPRINT("Offset: %hx\n", Offset);
115
116 Offset += ((USHORT)Source & 0x000F);
117 DPRINT("Offset: %hx\n", Offset);
118
119 Offset = NlsUnicodeLowercaseTable[Offset];
120 DPRINT("Offset: %hx\n", Offset);
121
122 DPRINT("Result: %hx\n", Source + (SHORT)Offset);
123
124 return Source + (SHORT)Offset;
125 }
126
127 /*
128 * @implemented
129 */
130 WCHAR NTAPI
131 RtlDowncaseUnicodeChar(IN WCHAR Source)
132 {
133 PAGED_CODE_RTL();
134
135 return RtlpDowncaseUnicodeChar(Source);
136 }
137
138 /*
139 * @implemented
140 */
141 VOID NTAPI
142 RtlGetDefaultCodePage(OUT PUSHORT AnsiCodePage,
143 OUT PUSHORT OemCodePage)
144 {
145 PAGED_CODE_RTL();
146
147 *AnsiCodePage = NlsAnsiCodePage;
148 *OemCodePage = NlsOemCodePage;
149 }
150
151 /*
152 * @implemented
153 */
154 VOID NTAPI
155 RtlInitCodePageTable(IN PUSHORT TableBase,
156 OUT PCPTABLEINFO CodePageTable)
157 {
158 PNLS_FILE_HEADER NlsFileHeader;
159
160 PAGED_CODE_RTL();
161
162 DPRINT("RtlInitCodePageTable() called\n");
163
164 NlsFileHeader = (PNLS_FILE_HEADER)TableBase;
165
166 /* Copy header fields first */
167 CodePageTable->CodePage = NlsFileHeader->CodePage;
168 CodePageTable->MaximumCharacterSize = NlsFileHeader->MaximumCharacterSize;
169 CodePageTable->DefaultChar = NlsFileHeader->DefaultChar;
170 CodePageTable->UniDefaultChar = NlsFileHeader->UniDefaultChar;
171 CodePageTable->TransDefaultChar = NlsFileHeader->TransDefaultChar;
172 CodePageTable->TransUniDefaultChar = NlsFileHeader->TransUniDefaultChar;
173
174 RtlCopyMemory(&CodePageTable->LeadByte,
175 &NlsFileHeader->LeadByte,
176 MAXIMUM_LEADBYTES);
177
178 /* Offset to wide char table is after the header */
179 CodePageTable->WideCharTable =
180 TableBase + NlsFileHeader->HeaderSize + 1 + TableBase[NlsFileHeader->HeaderSize];
181
182 /* Then multibyte table (256 wchars) follows */
183 CodePageTable->MultiByteTable = TableBase + NlsFileHeader->HeaderSize + 1;
184
185 /* Check the presence of glyph table (256 wchars) */
186 if (!CodePageTable->MultiByteTable[256])
187 CodePageTable->DBCSRanges = CodePageTable->MultiByteTable + 256 + 1;
188 else
189 CodePageTable->DBCSRanges = CodePageTable->MultiByteTable + 256 + 1 + 256;
190
191 /* Is this double-byte code page? */
192 if (*CodePageTable->DBCSRanges)
193 {
194 CodePageTable->DBCSCodePage = 1;
195 CodePageTable->DBCSOffsets = CodePageTable->DBCSRanges + 1;
196 }
197 else
198 {
199 CodePageTable->DBCSCodePage = 0;
200 CodePageTable->DBCSOffsets = NULL;
201 }
202 }
203
204 /*
205 * @implemented
206 */
207 VOID NTAPI
208 RtlInitNlsTables(IN PUSHORT AnsiTableBase,
209 IN PUSHORT OemTableBase,
210 IN PUSHORT CaseTableBase,
211 OUT PNLSTABLEINFO NlsTable)
212 {
213 PAGED_CODE_RTL();
214
215 DPRINT("RtlInitNlsTables()called\n");
216
217 if (AnsiTableBase && OemTableBase && CaseTableBase)
218 {
219 RtlInitCodePageTable(AnsiTableBase, &NlsTable->AnsiTableInfo);
220 RtlInitCodePageTable(OemTableBase, &NlsTable->OemTableInfo);
221
222 NlsTable->UpperCaseTable = (PUSHORT)CaseTableBase + 2;
223 NlsTable->LowerCaseTable = (PUSHORT)CaseTableBase + *((PUSHORT)CaseTableBase + 1) + 2;
224 }
225 }
226
227 /*
228 * @unimplemented
229 */
230 NTSTATUS NTAPI
231 RtlMultiByteToUnicodeN(OUT PWCHAR UnicodeString,
232 IN ULONG UnicodeSize,
233 OUT PULONG ResultSize,
234 IN PCSTR MbString,
235 IN ULONG MbSize)
236 {
237 ULONG Size = 0;
238 ULONG i;
239
240 PAGED_CODE_RTL();
241
242 if (!NlsMbCodePageTag)
243 {
244 /* single-byte code page */
245 if (MbSize > (UnicodeSize / sizeof(WCHAR)))
246 Size = UnicodeSize / sizeof(WCHAR);
247 else
248 Size = MbSize;
249
250 if (ResultSize)
251 *ResultSize = Size * sizeof(WCHAR);
252
253 for (i = 0; i < Size; i++)
254 UnicodeString[i] = NlsAnsiToUnicodeTable[(UCHAR)MbString[i]];
255 }
256 else
257 {
258 /* multi-byte code page */
259 /* FIXME */
260
261 UCHAR Char;
262 USHORT LeadByteInfo;
263 PCSTR MbEnd = MbString + MbSize;
264
265 for (i = 0; i < UnicodeSize / sizeof(WCHAR) && MbString < MbEnd; i++)
266 {
267 Char = *(PUCHAR)MbString++;
268
269 if (Char < 0x80)
270 {
271 *UnicodeString++ = Char;
272 continue;
273 }
274
275 LeadByteInfo = NlsLeadByteInfo[Char];
276
277 if (!LeadByteInfo)
278 {
279 *UnicodeString++ = NlsAnsiToUnicodeTable[Char];
280 continue;
281 }
282
283 if (MbString < MbEnd)
284 *UnicodeString++ = NlsLeadByteInfo[LeadByteInfo + *(PUCHAR)MbString++];
285 }
286
287 if (ResultSize)
288 *ResultSize = i * sizeof(WCHAR);
289 }
290
291 return STATUS_SUCCESS;
292 }
293
294 /*
295 * @unimplemented
296 */
297 NTSTATUS
298 NTAPI
299 RtlConsoleMultiByteToUnicodeN(OUT PWCHAR UnicodeString,
300 IN ULONG UnicodeSize,
301 OUT PULONG ResultSize,
302 IN PCSTR MbString,
303 IN ULONG MbSize,
304 OUT PULONG Unknown)
305 {
306 PAGED_CODE_RTL();
307
308 UNIMPLEMENTED;
309 DPRINT1("RtlConsoleMultiByteToUnicodeN calling RtlMultiByteToUnicodeN\n");
310 *Unknown = 1;
311 return RtlMultiByteToUnicodeN(UnicodeString,
312 UnicodeSize,
313 ResultSize,
314 MbString,
315 MbSize);
316 }
317
318 /*
319 * @implemented
320 */
321 NTSTATUS
322 NTAPI
323 RtlMultiByteToUnicodeSize(OUT PULONG UnicodeSize,
324 IN PCSTR MbString,
325 IN ULONG MbSize)
326 {
327 ULONG Length = 0;
328
329 PAGED_CODE_RTL();
330
331 if (!NlsMbCodePageTag)
332 {
333 /* single-byte code page */
334 *UnicodeSize = MbSize * sizeof (WCHAR);
335 }
336 else
337 {
338 /* multi-byte code page */
339 /* FIXME */
340
341 while (MbSize--)
342 {
343 UCHAR Char = *(PUCHAR)MbString++;
344
345 if (Char >= 0x80 && NlsLeadByteInfo[Char])
346 {
347 if (MbSize)
348 {
349 /* Move on */
350 MbSize--;
351 MbString++;
352 }
353 }
354
355 /* Increase returned size */
356 Length++;
357 }
358
359 /* Return final size */
360 *UnicodeSize = Length * sizeof(WCHAR);
361 }
362
363 /* Success */
364 return STATUS_SUCCESS;
365 }
366
367 /*
368 * @unimplemented
369 */
370 NTSTATUS NTAPI
371 RtlOemToUnicodeN(OUT PWCHAR UnicodeString,
372 IN ULONG UnicodeSize,
373 OUT PULONG ResultSize OPTIONAL,
374 IN PCCH OemString,
375 IN ULONG OemSize)
376 {
377 ULONG Size = 0;
378 ULONG i;
379
380 PAGED_CODE_RTL();
381
382 if (!NlsMbOemCodePageTag)
383 {
384 /* single-byte code page */
385 if (OemSize > (UnicodeSize / sizeof(WCHAR)))
386 Size = UnicodeSize / sizeof(WCHAR);
387 else
388 Size = OemSize;
389
390 if (ResultSize)
391 *ResultSize = Size * sizeof(WCHAR);
392
393 for (i = 0; i < Size; i++)
394 {
395 *UnicodeString = NlsOemToUnicodeTable[(UCHAR)*OemString];
396 UnicodeString++;
397 OemString++;
398 }
399 }
400 else
401 {
402 /* multi-byte code page */
403 /* FIXME */
404
405 UCHAR Char;
406 USHORT OemLeadByteInfo;
407 PCCH OemEnd = OemString + OemSize;
408
409 for (i = 0; i < UnicodeSize / sizeof(WCHAR) && OemString < OemEnd; i++)
410 {
411 Char = *(PUCHAR)OemString++;
412
413 if (Char < 0x80)
414 {
415 *UnicodeString++ = Char;
416 continue;
417 }
418
419 OemLeadByteInfo = NlsOemLeadByteInfo[Char];
420
421 if (!OemLeadByteInfo)
422 {
423 *UnicodeString++ = NlsOemToUnicodeTable[Char];
424 continue;
425 }
426
427 if (OemString < OemEnd)
428 *UnicodeString++ =
429 NlsOemLeadByteInfo[OemLeadByteInfo + *(PUCHAR)OemString++];
430 }
431
432 if (ResultSize)
433 *ResultSize = i * sizeof(WCHAR);
434 }
435
436 return STATUS_SUCCESS;
437 }
438
439 /*
440 * @implemented
441 */
442 VOID NTAPI
443 RtlResetRtlTranslations(IN PNLSTABLEINFO NlsTable)
444 {
445 PAGED_CODE_RTL();
446
447 DPRINT("RtlResetRtlTranslations() called\n");
448
449 /* Set ANSI data */
450 NlsAnsiToUnicodeTable = (PUSHORT)NlsTable->AnsiTableInfo.MultiByteTable;
451 NlsUnicodeToAnsiTable = NlsTable->AnsiTableInfo.WideCharTable;
452 NlsUnicodeToMbAnsiTable = (PUSHORT)NlsTable->AnsiTableInfo.WideCharTable;
453 NlsMbCodePageTag = (NlsTable->AnsiTableInfo.DBCSCodePage != 0);
454 NlsLeadByteInfo = NlsTable->AnsiTableInfo.DBCSOffsets;
455 NlsAnsiCodePage = NlsTable->AnsiTableInfo.CodePage;
456 DPRINT("Ansi codepage %hu\n", NlsAnsiCodePage);
457
458 /* Set OEM data */
459 NlsOemToUnicodeTable = (PUSHORT)NlsTable->OemTableInfo.MultiByteTable;
460 NlsUnicodeToOemTable = NlsTable->OemTableInfo.WideCharTable;
461 NlsUnicodeToMbOemTable = (PUSHORT)NlsTable->OemTableInfo.WideCharTable;
462 NlsMbOemCodePageTag = (NlsTable->OemTableInfo.DBCSCodePage != 0);
463 NlsOemLeadByteInfo = NlsTable->OemTableInfo.DBCSOffsets;
464 NlsOemCodePage = NlsTable->OemTableInfo.CodePage;
465 DPRINT("Oem codepage %hu\n", NlsOemCodePage);
466
467 /* Set Unicode case map data */
468 NlsUnicodeUpcaseTable = NlsTable->UpperCaseTable;
469 NlsUnicodeLowercaseTable = NlsTable->LowerCaseTable;
470
471 /* set the default characters for RtlpDidUnicodeToOemWork */
472 NlsOemDefaultChar = NlsTable->OemTableInfo.DefaultChar;
473 NlsUnicodeDefaultChar = NlsTable->OemTableInfo.TransDefaultChar;
474 }
475
476 /*
477 * @unimplemented
478 */
479 NTSTATUS NTAPI
480 RtlUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
481 OUT PCHAR CustomString,
482 IN ULONG CustomSize,
483 OUT PULONG ResultSize OPTIONAL,
484 IN PWCHAR UnicodeString,
485 IN ULONG UnicodeSize)
486 {
487 ULONG Size = 0;
488 ULONG i;
489
490 PAGED_CODE_RTL();
491
492 if (!CustomCP->DBCSCodePage)
493 {
494 /* single-byte code page */
495 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
496 Size = CustomSize;
497 else
498 Size = UnicodeSize / sizeof(WCHAR);
499
500 if (ResultSize)
501 *ResultSize = Size;
502
503 for (i = 0; i < Size; i++)
504 {
505 *CustomString = ((PCHAR)CustomCP->WideCharTable)[*UnicodeString];
506 CustomString++;
507 UnicodeString++;
508 }
509 }
510 else
511 {
512 /* multi-byte code page */
513 /* FIXME */
514 ASSERT(FALSE);
515 }
516
517 return STATUS_SUCCESS;
518 }
519
520 /*
521 * @unimplemented
522 */
523 NTSTATUS NTAPI
524 RtlUnicodeToMultiByteN(OUT PCHAR MbString,
525 IN ULONG MbSize,
526 OUT PULONG ResultSize OPTIONAL,
527 IN PCWCH UnicodeString,
528 IN ULONG UnicodeSize)
529 {
530 ULONG Size = 0;
531 ULONG i;
532
533 PAGED_CODE_RTL();
534
535 if (!NlsMbCodePageTag)
536 {
537 /* single-byte code page */
538 Size = (UnicodeSize > (MbSize * sizeof (WCHAR)))
539 ? MbSize : (UnicodeSize / sizeof (WCHAR));
540
541 if (ResultSize)
542 *ResultSize = Size;
543
544 for (i = 0; i < Size; i++)
545 {
546 *MbString++ = NlsUnicodeToAnsiTable[*UnicodeString++];
547 }
548 }
549 else
550 {
551 /* multi-byte code page */
552 /* FIXME */
553
554 USHORT WideChar;
555 USHORT MbChar;
556
557 for (i = MbSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--)
558 {
559 WideChar = *UnicodeString++;
560
561 if (WideChar < 0x80)
562 {
563 *MbString++ = LOBYTE(WideChar);
564 continue;
565 }
566
567 MbChar = NlsUnicodeToMbAnsiTable[WideChar];
568
569 if (!HIBYTE(MbChar))
570 {
571 *MbString++ = LOBYTE(MbChar);
572 continue;
573 }
574
575 if (i >= 2)
576 {
577 *MbString++ = HIBYTE(MbChar);
578 *MbString++ = LOBYTE(MbChar);
579 i--;
580 }
581 else break;
582 }
583
584 if (ResultSize)
585 *ResultSize = MbSize - i;
586 }
587
588 return STATUS_SUCCESS;
589 }
590
591 /*
592 * @implemented
593 */
594 NTSTATUS
595 NTAPI
596 RtlUnicodeToMultiByteSize(OUT PULONG MbSize,
597 IN PCWCH UnicodeString,
598 IN ULONG UnicodeSize)
599 {
600 ULONG UnicodeLength = UnicodeSize / sizeof(WCHAR);
601 ULONG MbLength = 0;
602
603 PAGED_CODE_RTL();
604
605 if (!NlsMbCodePageTag)
606 {
607 /* single-byte code page */
608 *MbSize = UnicodeLength;
609 }
610 else
611 {
612 /* multi-byte code page */
613 /* FIXME */
614
615 while (UnicodeLength--)
616 {
617 USHORT WideChar = *UnicodeString++;
618
619 if (WideChar >= 0x80 && HIBYTE(NlsUnicodeToMbAnsiTable[WideChar]))
620 {
621 MbLength += sizeof(WCHAR);
622 }
623 else
624 {
625 MbLength++;
626 }
627 }
628
629 *MbSize = MbLength;
630 }
631
632 /* Success */
633 return STATUS_SUCCESS;
634 }
635
636 /*
637 * @unimplemented
638 */
639 NTSTATUS NTAPI
640 RtlUnicodeToOemN(OUT PCHAR OemString,
641 IN ULONG OemSize,
642 OUT PULONG ResultSize OPTIONAL,
643 IN PCWCH UnicodeString,
644 IN ULONG UnicodeSize)
645 {
646 ULONG Size = 0;
647 ULONG i;
648
649 PAGED_CODE_RTL();
650
651 if (!NlsMbOemCodePageTag)
652 {
653 /* single-byte code page */
654 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
655 Size = OemSize;
656 else
657 Size = UnicodeSize / sizeof(WCHAR);
658
659 if (ResultSize)
660 *ResultSize = Size;
661
662 for (i = 0; i < Size; i++)
663 {
664 *OemString = NlsUnicodeToOemTable[*UnicodeString];
665 OemString++;
666 UnicodeString++;
667 }
668 }
669 else
670 {
671 /* multi-byte code page */
672 /* FIXME */
673
674 USHORT WideChar;
675 USHORT OemChar;
676
677 for (i = OemSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--)
678 {
679 WideChar = *UnicodeString++;
680
681 if (WideChar < 0x80)
682 {
683 *OemString++ = LOBYTE(WideChar);
684 continue;
685 }
686
687 OemChar = NlsUnicodeToMbOemTable[WideChar];
688
689 if (!HIBYTE(OemChar))
690 {
691 *OemString++ = LOBYTE(OemChar);
692 continue;
693 }
694
695 if (i >= 2)
696 {
697 *OemString++ = HIBYTE(OemChar);
698 *OemString++ = LOBYTE(OemChar);
699 i--;
700 }
701 else break;
702 }
703
704 if (ResultSize)
705 *ResultSize = OemSize - i;
706 }
707
708 return STATUS_SUCCESS;
709 }
710
711 /*
712 * @implemented
713 */
714 WCHAR NTAPI
715 RtlpUpcaseUnicodeChar(IN WCHAR Source)
716 {
717 USHORT Offset;
718
719 if (Source < 'a')
720 return Source;
721
722 if (Source <= 'z')
723 return (Source - ('a' - 'A'));
724
725 Offset = ((USHORT)Source >> 8) & 0xFF;
726 Offset = NlsUnicodeUpcaseTable[Offset];
727
728 Offset += ((USHORT)Source >> 4) & 0xF;
729 Offset = NlsUnicodeUpcaseTable[Offset];
730
731 Offset += ((USHORT)Source & 0xF);
732 Offset = NlsUnicodeUpcaseTable[Offset];
733
734 return Source + (SHORT)Offset;
735 }
736
737 /*
738 * @implemented
739 */
740 WCHAR NTAPI
741 RtlUpcaseUnicodeChar(IN WCHAR Source)
742 {
743 PAGED_CODE_RTL();
744
745 return RtlpUpcaseUnicodeChar(Source);
746 }
747
748 /*
749 * @implemented
750 */
751 NTSTATUS NTAPI
752 RtlUpcaseUnicodeToCustomCPN(IN PCPTABLEINFO CustomCP,
753 OUT PCHAR CustomString,
754 IN ULONG CustomSize,
755 OUT PULONG ResultSize OPTIONAL,
756 IN PWCHAR UnicodeString,
757 IN ULONG UnicodeSize)
758 {
759 WCHAR UpcaseChar;
760 ULONG Size = 0;
761 ULONG i;
762
763 PAGED_CODE_RTL();
764
765 if (!CustomCP->DBCSCodePage)
766 {
767 /* single-byte code page */
768 if (UnicodeSize > (CustomSize * sizeof(WCHAR)))
769 Size = CustomSize;
770 else
771 Size = UnicodeSize / sizeof(WCHAR);
772
773 if (ResultSize)
774 *ResultSize = Size;
775
776 for (i = 0; i < Size; i++)
777 {
778 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString);
779 *CustomString = ((PCHAR)CustomCP->WideCharTable)[UpcaseChar];
780 ++CustomString;
781 ++UnicodeString;
782 }
783 }
784 else
785 {
786 /* multi-byte code page */
787 /* FIXME */
788 ASSERT(FALSE);
789 }
790
791 return STATUS_SUCCESS;
792 }
793
794 /*
795 * @unimplemented
796 */
797 NTSTATUS NTAPI
798 RtlUpcaseUnicodeToMultiByteN(OUT PCHAR MbString,
799 IN ULONG MbSize,
800 OUT PULONG ResultSize OPTIONAL,
801 IN PCWCH UnicodeString,
802 IN ULONG UnicodeSize)
803 {
804 WCHAR UpcaseChar;
805 ULONG Size = 0;
806 ULONG i;
807
808 PAGED_CODE_RTL();
809
810 if (!NlsMbCodePageTag)
811 {
812 /* single-byte code page */
813 if (UnicodeSize > (MbSize * sizeof(WCHAR)))
814 Size = MbSize;
815 else
816 Size = UnicodeSize / sizeof(WCHAR);
817
818 if (ResultSize)
819 *ResultSize = Size;
820
821 for (i = 0; i < Size; i++)
822 {
823 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString);
824 *MbString = NlsUnicodeToAnsiTable[UpcaseChar];
825 MbString++;
826 UnicodeString++;
827 }
828 }
829 else
830 {
831 /* multi-byte code page */
832 /* FIXME */
833 ASSERT(FALSE);
834 }
835
836 return STATUS_SUCCESS;
837 }
838
839 /*
840 * @unimplemented
841 */
842 NTSTATUS NTAPI
843 RtlUpcaseUnicodeToOemN(OUT PCHAR OemString,
844 IN ULONG OemSize,
845 OUT PULONG ResultSize OPTIONAL,
846 IN PCWCH UnicodeString,
847 IN ULONG UnicodeSize)
848 {
849 WCHAR UpcaseChar;
850 ULONG Size = 0;
851 ULONG i;
852
853 PAGED_CODE_RTL();
854
855 ASSERT(NlsUnicodeToOemTable != NULL);
856
857 if (!NlsMbOemCodePageTag)
858 {
859 /* single-byte code page */
860 if (UnicodeSize > (OemSize * sizeof(WCHAR)))
861 Size = OemSize;
862 else
863 Size = UnicodeSize / sizeof(WCHAR);
864
865 if (ResultSize)
866 *ResultSize = Size;
867
868 for (i = 0; i < Size; i++)
869 {
870 UpcaseChar = RtlpUpcaseUnicodeChar(*UnicodeString);
871 *OemString = NlsUnicodeToOemTable[UpcaseChar];
872 OemString++;
873 UnicodeString++;
874 }
875 }
876 else
877 {
878 /* multi-byte code page */
879 /* FIXME */
880
881 USHORT WideChar;
882 USHORT OemChar;
883
884 for (i = OemSize, Size = UnicodeSize / sizeof(WCHAR); i && Size; i--, Size--)
885 {
886 WideChar = RtlpUpcaseUnicodeChar(*UnicodeString++);
887
888 if (WideChar < 0x80)
889 {
890 *OemString++ = LOBYTE(WideChar);
891 continue;
892 }
893
894 OemChar = NlsUnicodeToMbOemTable[WideChar];
895
896 if (!HIBYTE(OemChar))
897 {
898 *OemString++ = LOBYTE(OemChar);
899 continue;
900 }
901
902 if (i >= 2)
903 {
904 *OemString++ = HIBYTE(OemChar);
905 *OemString++ = LOBYTE(OemChar);
906 i--;
907 }
908 else break;
909 }
910
911 if (ResultSize)
912 *ResultSize = OemSize - i;
913 }
914
915 return STATUS_SUCCESS;
916 }
917
918 /*
919 * @unimplemented
920 */
921 CHAR NTAPI
922 RtlUpperChar(IN CHAR Source)
923 {
924 WCHAR Unicode;
925 CHAR Destination;
926
927 PAGED_CODE_RTL();
928
929 /* Check for simple ANSI case */
930 if (Source <= 'z')
931 {
932 /* Check for simple downcase a-z case */
933 if (Source >= 'a')
934 {
935 /* Just XOR with the difference */
936 return Source ^ ('a' - 'A');
937 }
938 else
939 {
940 /* Otherwise return the same char, it's already upcase */
941 return Source;
942 }
943 }
944 else
945 {
946 if (!NlsMbCodePageTag)
947 {
948 /* single-byte code page */
949
950 /* ansi->unicode */
951 Unicode = NlsAnsiToUnicodeTable[(UCHAR)Source];
952
953 /* upcase conversion */
954 Unicode = RtlpUpcaseUnicodeChar (Unicode);
955
956 /* unicode -> ansi */
957 Destination = NlsUnicodeToAnsiTable[(USHORT)Unicode];
958 }
959 else
960 {
961 /* multi-byte code page */
962 /* FIXME */
963 Destination = Source;
964 }
965 }
966
967 return Destination;
968 }
969
970 /* EOF */