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