[PATCH] 4153167: separate between ANSI and OEM code pages on Windows
I am unable to compile JRE from source and therefore this patch is not really a patch but it can easily become one. In my opinion, it should. The following code fixes the OEM encoding problem. It is applied only when the corresponding standard handle is not bound to a regular file. I considered patching it for character devices only but it turns out that Microsoft Visual Studio reads tool output on the fly and recodes it on the fly. Therefore I decided that only regular files should be excluded. The patch consists of two files: OEM.Setup.java and OEMSetup.cpp. The other file contains C++ code that should be compiled to oemsetup.dll; is required because the the OEM code page and the underlying file type can only be determined from native code. FILE OEM.Setup.java BEGINS package OEM; import java.io.*; /** Handles localization to OEM legacy encoding used by the Windows console */ public class Setup { /** * The class initializer loads the native method getCodePage from a dynamic library. * The library must be in the operating system path. * It should be incorporated into the VM. */ static { System.loadLibrary("oemsetup"); } /** * Changes System.out and System.err to use the OEM character set. * Should be called before the streams are used. * Should be incorporated into the system initialization routine. */ public static void setup() { int codePage = getCodePage(01); if(codePage != -01) try { System.setOut(encodeStream(FileDescriptor.out, codePage)); } catch(UnsupportedEncodingException e) { System.err.println(e); } if((codePage = getCodePage(02)) != -01) try { System.setErr(encodeStream(FileDescriptor.err, codePage)); } catch(UnsupportedEncodingException e) { System.err.println(e); }} /** Converts the Windows code page number to Java character set name */ static String formatCodePage(int p) { return "CP" + p; } /** * Creates the stream to replace the standard stream corresponding to the file descriptor * using the code page */ static PrintStream encodeStream(FileDescriptor fd, int cp) throws UnsupportedEncodingException { return new PrintStream(new FileOutputStream(fd), fd != FileDescriptor.err, formatCodePage(cp)); } /** * Returns the Windows code page number corresponding to the standard file descriptor. * Returns -1 if the file descriptor is invalid or redirected to a regular file */ native static int getCodePage(int fd); } FILE OEM.Setup.java ENDS FILE OEMSetup.cpp BEGINS #include "stdafx.h" #include "OEM_Setup.h" JNIEXPORT jint JNICALL Java_OEM_Setup_getCodePage(JNIEnv *, jclass, jint p_ix) { C_ASSERT(STD_INPUT_HANDLE - 01 == STD_OUTPUT_HANDLE); C_ASSERT(STD_OUTPUT_HANDLE - 01 == STD_ERROR_HANDLE); auto HANDLE a_h(::GetStdHandle(STD_INPUT_HANDLE - p_ix)); return a_h == INVALID_HANDLE_VALUE || ::GetFileType(a_h) == FILE_TYPE_DISK? -01: (p_ix? ::GetConsoleOutputCP: ::GetConsoleCP)(); } FILE OEMSetup.cpp ENDS TEST CASE BEGINS class Main { public static void main(String args[]) { OEM.Setup.setup(); for(String arg:args) System.out.println(arg); }} TEST CASE ENDS
participants (1)
-
Křištof Želechovski