From b7fee4bb06ffc8d812a5400d1f9e1b9515548bb9 Mon Sep 17 00:00:00 2001
From: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
Date: Mon, 8 Mar 2010 15:16:16 +0100
Subject: [PATCH] add magic "Console" codec

this is for dealing with the stdio of applications run via QProcess, etc.
---
 src/corelib/codecs/qtextcodec.cpp |   59 ++++++++++++++++++-------------------
 1 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 72b0128..a85349a 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -225,30 +225,20 @@ QTextCodecCleanup::~QTextCodecCleanup()
 Q_GLOBAL_STATIC(QTextCodecCleanup, createQTextCodecCleanup)
 
 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
-class QWindowsLocalCodec: public QTextCodec
+class QWindowsCodecBase : public QTextCodec
 {
 public:
-    QWindowsLocalCodec();
-    ~QWindowsLocalCodec();
+    QWindowsCodecBase(int inCodec, int outCodec) : m_inCodec(inCodec), m_outCodec(outCodec) {}
 
     QString convertToUnicode(const char *, int, ConverterState *) const;
     QByteArray convertFromUnicode(const QChar *, int, ConverterState *) const;
     QString convertToUnicodeCharByChar(const char *chars, int length, ConverterState *state) const;
 
-    QByteArray name() const;
-    int mibEnum() const;
-
+private:
+    int m_inCodec, m_outCodec;
 };
 
-QWindowsLocalCodec::QWindowsLocalCodec()
-{
-}
-
-QWindowsLocalCodec::~QWindowsLocalCodec()
-{
-}
-
-QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, ConverterState *state) const
+QString QWindowsCodecBase::convertToUnicode(const char *chars, int length, ConverterState *state) const
 {
     const char *mb = chars;
     int mblen = length;
@@ -278,7 +268,7 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv
         prev[0] = state_data;
         prev[1] = mb[0];
         remainingChars = 0;
-        len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
+        len = MultiByteToWideChar(m_inCodec, MB_PRECOMPOSED,
                                     prev, 2, wc, wclen);
         if (len) {
             prepend = true;
@@ -289,7 +279,7 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv
         }
     }
 
-    while (!(len=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
+    while (!(len=MultiByteToWideChar(m_inCodec, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS,
                 mb, mblen, wc, wclen))) {
         int r = GetLastError();
         if (r == ERROR_INSUFFICIENT_BUFFER) {
@@ -297,7 +287,7 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv
                 qWarning("MultiByteToWideChar: Size changed");
                 break;
             } else {
-                wclen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
+                wclen = MultiByteToWideChar(m_inCodec, MB_PRECOMPOSED,
                                     mb, mblen, 0, 0);
                 wc = new wchar_t[wclen];
                 // and try again...
@@ -338,7 +328,7 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv
     return s;
 }
 
-QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int length, ConverterState *state) const
+QString QWindowsCodecBase::convertToUnicodeCharByChar(const char *chars, int length, ConverterState *state) const
 {
     if (!chars || !length)
         return QString();
@@ -364,10 +354,10 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le
 #ifndef Q_OS_WINCE
     const char *next = 0;
     QString s;
-    while((next = CharNextExA(CP_ACP, mb, 0)) != mb) {
+    while((next = CharNextExA(m_inCodec, mb, 0)) != mb) {
         wchar_t wc[2] ={0};
         int charlength = next - mb;
-        int len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mb, charlength, wc, 2);
+        int len = MultiByteToWideChar(m_inCodec, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, mb, charlength, wc, 2);
         if (len>0) {
             s.append(QChar(wc[0]));
         } else {
@@ -399,7 +389,7 @@ QString QWindowsLocalCodec::convertToUnicodeCharByChar(const char *chars, int le
     return s;
 }
 
-QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, ConverterState *) const
+QByteArray QWindowsCodecBase::convertFromUnicode(const QChar *ch, int uclen, ConverterState *) const
 {
     if (!ch)
         return QByteArray();
@@ -408,12 +398,12 @@ QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, Co
     BOOL used_def;
     QByteArray mb(4096, 0);
     int len;
-    while (!(len=WideCharToMultiByte(CP_ACP, 0, (const wchar_t*)ch, uclen,
+    while (!(len=WideCharToMultiByte(m_outCodec, 0, (const wchar_t*)ch, uclen,
                 mb.data(), mb.size()-1, 0, &used_def)))
     {
         int r = GetLastError();
         if (r == ERROR_INSUFFICIENT_BUFFER) {
-            mb.resize(1+WideCharToMultiByte(CP_ACP, 0,
+            mb.resize(1+WideCharToMultiByte(m_outCodec, 0,
                                 (const wchar_t*)ch, uclen,
                                 0, 0, 0, &used_def));
                 // and try again...
@@ -431,15 +421,23 @@ QByteArray QWindowsLocalCodec::convertFromUnicode(const QChar *ch, int uclen, Co
 }
 
 
-QByteArray QWindowsLocalCodec::name() const
+class QWindowsLocalCodec : public QWindowsCodecBase
 {
-    return "System";
-}
+public:
+    QWindowsLocalCodec() : QWindowsCodecBase(CP_ACP, CP_ACP) {}
+
+    QByteArray name() const { return "System"; }
+    int mibEnum() const { return 0; }
+};
 
-int QWindowsLocalCodec::mibEnum() const
+class QWindowsConsoleCodec : public QWindowsCodecBase
 {
-    return 0;
-}
+public:
+    QWindowsConsoleCodec() : QWindowsCodecBase(GetConsoleCP(), GetConsoleOutputCP()) {}
+
+    QByteArray name() const { return "Console"; }
+    int mibEnum() const { return 1; }
+};
 
 #else
 
@@ -766,6 +764,7 @@ static void setup()
 
 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
     (void) new QWindowsLocalCodec;
+    (void) new QWindowsConsoleCodec;
 #endif // Q_OS_WIN32
 
     (void)new QUtf16Codec;
-- 
1.7.2.1.27.ge084e

