update for HEAD-2003021201
[reactos.git] / lib / kernel32 / misc / mbchars.c
diff --git a/lib/kernel32/misc/mbchars.c b/lib/kernel32/misc/mbchars.c
new file mode 100644 (file)
index 0000000..32e5135
--- /dev/null
@@ -0,0 +1,302 @@
+/* $Id$
+ *
+ */
+#include <windows.h>
+
+
+/**********************************************************************
+ * NAME                         PRIVATE
+ *  IsInstalledCP@4
+ *
+ * RETURN VALUE
+ *  TRUE if CodePage is installed in the system.
+ */
+static
+BOOL
+STDCALL
+IsInstalledCP(UINT CodePage)
+{
+    /* FIXME */
+    return TRUE;
+}
+
+
+/**********************************************************************
+ * NAME                         EXPORTED
+ *  MultiByteToWideChar@24
+ *
+ * ARGUMENTS
+ *  CodePage
+ *      CP_ACP      ANSI code page
+ *      CP_MACCP    Macintosh code page
+ *      CP_OEMCP    OEM code page
+ *      (UINT)      Any installed code page
+ *
+ *  dwFlags
+ *      MB_PRECOMPOSED
+ *      MB_COMPOSITE
+ *      MB_ERR_INVALID_CHARS
+ *      MB_USEGLYPHCHARS
+ *
+ *  lpMultiByteStr
+ *      Input buffer;
+ *
+ *  cchMultiByte
+ *      Size of MultiByteStr, or -1 if MultiByteStr is
+ *      NULL terminated;
+ *
+ *  lpWideCharStr
+ *      Output buffer;
+ *
+ *  cchWideChar
+ *      Size (in WCHAR unit) of WideCharStr, or 0
+ *      if the caller just wants to know how large
+ *      WideCharStr should be for a successful
+ *      conversion.
+ *
+ * RETURN VALUE
+ *  0 on error; otherwise the number of WCHAR written
+ *  in the WideCharStr buffer.
+ *
+ * NOTE
+ *  A raw converter for now. It assumes lpMultiByteStr is
+ *  NEVER multi-byte (that is each input character is
+ *  8-bit ASCII) and is ALWAYS NULL terminated.
+ *  FIXME-FIXME-FIXME-FIXME
+ */
+INT
+STDCALL
+MultiByteToWideChar(
+    UINT    CodePage,
+    DWORD   dwFlags,
+    LPCSTR  lpMultiByteStr,
+    int     cchMultiByte,
+    LPWSTR  lpWideCharStr,
+    int     cchWideChar)
+{
+    int InStringLength = 0;
+    PCHAR   r;
+    PWCHAR  w;
+    int cchConverted;
+
+    /*
+     * Check the parameters.
+     */
+    if (/* --- CODE PAGE --- */
+        (  (CP_ACP != CodePage)
+                && (CP_MACCP != CodePage)
+                && (CP_OEMCP != CodePage)
+                && (FALSE == IsInstalledCP(CodePage)) )
+        /* --- FLAGS --- */
+        || (dwFlags & ~(MB_PRECOMPOSED | MB_COMPOSITE |
+                        MB_ERR_INVALID_CHARS | MB_USEGLYPHCHARS))
+        /* --- INPUT BUFFER --- */
+        || (NULL == lpMultiByteStr)  )
+    {
+        SetLastError (ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+    /*
+     * Compute the input buffer length.
+     */
+    //if (-1 == cchMultiByte)
+    if (cchMultiByte < 0)
+    {
+        InStringLength = lstrlen(lpMultiByteStr) + 1;
+    }
+    else
+    {
+        InStringLength = cchMultiByte;
+    }
+    /*
+     * Does caller query for output
+     * buffer size?
+     */
+    if (0 == cchWideChar)
+    {
+        //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
+        return InStringLength;
+    }
+    /*
+     * Is space provided for the translated
+     * string enough?
+     */
+    if (cchWideChar < InStringLength)
+    {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return 0;
+    }
+    /*
+     * Raw 8- to 16-bit conversion.
+     */
+    for (cchConverted = 0,
+        r = (PCHAR)lpMultiByteStr,
+        w = (PWCHAR)lpWideCharStr;
+
+        cchConverted < InStringLength;
+
+        r++,
+        w++,
+        cchConverted++)
+    {
+        *w = (WCHAR)*r;
+    }
+    /*
+     * Return how many characters we
+     * wrote in the output buffer.
+     */
+    //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
+    return cchConverted;
+}
+
+
+/**********************************************************************
+ * NAME                         EXPORTED
+ *  WideCharToMultiByte@32
+ * 
+ *  Not yet implemented complete (without NLS so far)
+ *
+ * ARGUMENTS
+ *  CodePage
+ *      CP_ACP ANSI code page 
+ *      CP_MACCP Macintosh code page 
+ *      CP_OEMCP OEM code page 
+ *      CP_SYMBOL Symbol code page (42) 
+ *      CP_THREAD_ACP Current thread's ANSI code page 
+ *      CP_UTF7 Translate using UTF-7 
+ *      CP_UTF8 Translate using UTF-8 
+ *      (UINT)      Any installed code page
+ *
+ *  dwFlags
+ *      WC_NO_BEST_FIT_CHARS    
+ *      WC_COMPOSITECHECK Convert composite characters to precomposed characters. 
+ *      WC_DISCARDNS Discard nonspacing characters during conversion. 
+ *      WC_SEPCHARS Generate separate characters during conversion. This is the default conversion behavior. 
+ *      WC_DEFAULTCHAR Replace exceptions with the default character during conversion. 
+ *
+ *  lpWideCharStr 
+ *      Points to the wide-character string to be converted. 
+ *
+ *  cchWideChar
+ *      Size (in WCHAR unit) of WideCharStr, or 0
+ *      if the caller just wants to know how large
+ *      WideCharStr should be for a successful
+ *      conversion.
+ *  lpMultiByteStr 
+ *      Points to the buffer to receive the translated string. 
+ *  cchMultiByte 
+ *      Specifies the size in bytes of the buffer pointed to by the 
+ *      lpMultiByteStr parameter. If this value is zero, the function 
+ *      returns the number of bytes required for the buffer. 
+ *  lpDefaultChar 
+ *      Points to the character used if a wide character cannot be 
+ *      represented in the specified code page. If this parameter is 
+ *      NULL, a system default value is used. 
+        FIXME: ignored
+ *  lpUsedDefaultChar 
+ *      Points to a flag that indicates whether a default character was used. 
+ *      This parameter may be NULL. 
+        FIXME: allways set to FALSE.
+ *
+ *
+ *
+ * RETURN VALUE
+ *  0 on error; otherwise the number of bytes written
+ *  in the lpMultiByteStr buffer. Or the number of
+ *  bytes needed for the lpMultiByteStr buffer if cchMultiByte is zero.
+ *
+ * NOTE
+ *  A raw converter for now. It just cuts off the upper 9 Bit.
+ *  So the MBCS-string does not contain any LeadCharacters
+ *  FIXME - FIXME - FIXME - FIXME
+ */
+
+int
+STDCALL
+WideCharToMultiByte(
+    UINT    CodePage,
+    DWORD   dwFlags,
+    LPCWSTR lpWideCharStr,
+    int     cchWideChar,
+    LPSTR   lpMultiByteStr,
+    int     cchMultiByte,
+    LPCSTR  lpDefaultChar,
+    LPBOOL  lpUsedDefaultChar
+    )
+{
+    int wi, di;  // wide counter, dbcs byte count
+
+    /*
+     * Check the parameters.
+     */
+    if (    /* --- CODE PAGE --- */
+        (   (CP_ACP != CodePage)
+            && (CP_MACCP != CodePage)
+            && (CP_OEMCP != CodePage)
+            && (CP_SYMBOL != CodePage)
+            && (CP_THREAD_ACP != CodePage)
+            && (CP_UTF7 != CodePage)
+            && (CP_UTF8 != CodePage)
+            && (FALSE == IsInstalledCP (CodePage))
+            )
+        /* --- FLAGS --- */
+        || (dwFlags & ~(/*WC_NO_BEST_FIT_CHARS
+                |*/ WC_COMPOSITECHECK
+                | WC_DISCARDNS
+                | WC_SEPCHARS
+                | WC_DEFAULTCHAR
+                )
+            )
+        /* --- INPUT BUFFER --- */
+        || (NULL == lpWideCharStr)
+        )
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    // for now, make no difference but only convert cut the characters to 7Bit
+    //if (cchWideChar == -1) // assume its a 0-terminated str
+    if (cchWideChar < 0) // assume its a 0-terminated str
+    {           // and determine its length
+//        for (cchWideChar=0; lpWideCharStr[cchWideChar]!=0; cchWideChar++)
+//            cchWideChar++;
+        for (cchWideChar = 0; lpWideCharStr[cchWideChar] != 0; cchWideChar++) {
+        }
+        cchWideChar++; // length includes the null terminator
+    }
+
+    // user wants to determine needed space
+    if (cchMultiByte == 0) 
+    {
+        //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
+        return cchWideChar;         // FIXME: determine correct.
+    }
+    // the lpWideCharStr is cchWideChar characters long.
+    for (wi=0, di=0; wi<cchWideChar && di<cchMultiByte; ++wi, ++di)
+    {
+        // Flag and a not displayable char    FIXME
+        /*if( (dwFlags&WC_NO_BEST_FIT_CHARS) && (lpWideCharStr[wi] >127) ) 
+        {
+            lpMultiByteStr[di]=
+            *lpUsedDefaultChar = TRUE;
+
+        }*/
+        // FIXME
+        // just cut off the upper 9 Bit, since vals>=128 mean LeadByte.
+        lpMultiByteStr[di] = lpWideCharStr[wi] & 0x007F;
+    }
+    // has MultiByte exceeded but Wide is still in the string?
+    if (wi < cchWideChar && di >= cchMultiByte)
+    {
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return 0;
+    }
+    // else return # of bytes wirtten to MBCSbuffer (di)
+    //SetLastError(ERROR_SUCCESS); /* according to wine tests this shouldn't be touched on success.
+    // FIXME: move that elsewhere
+    if (lpUsedDefaultChar != NULL) *lpUsedDefaultChar = FALSE; 
+    return di;
+}
+
+/* EOF */