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