+/* Determine the number of bytes needed to represent a Wide character\r
+ as a MBCS character.\r
+\r
+ A single wide character may convert into a one, two, three, or four byte\r
+ narrow (MBCS or UTF-8) character. The number of MBCS bytes can be determined\r
+ as follows.\r
+\r
+ If WCS char < 0x00000080 One Byte\r
+ Else if WCS char < 0x0000D800 Two Bytes\r
+ Else Three Bytes\r
+\r
+ Since UEFI only supports the Unicode Base Multilingual Plane (BMP),\r
+ Four-byte characters are not supported.\r
+\r
+ @param[in] InCh Wide character to test.\r
+\r
+ @retval -1 Improperly formed character\r
+ @retval 0 InCh is 0x0000\r
+ @retval >0 Number of bytes needed for the MBCS character\r
+*/\r
+int\r
+EFIAPI\r
+OneWcToMcLen(const wchar_t InCh)\r
+{\r
+ ssize_t NumBytes;\r
+\r
+ if(InCh == 0) { // Is this a NUL, 0x0000 ?\r
+ NumBytes = 0;\r
+ }\r
+ else if(InCh < 0x0080) { // Is this a 1-byte character?\r
+ NumBytes = 1;\r
+ }\r
+ else if(InCh < 0x0800) { // Is this a 2-byte character?\r
+ NumBytes = 2;\r
+ }\r
+ else if((InCh >= 0xD800) && (InCh < 0xE000)) { // Is this a surrogate?\r
+ NumBytes = -1;\r
+ }\r
+ else {\r
+ NumBytes = 3; // Otherwise, it must be a 3-byte character.\r
+ }\r
+ return (int)NumBytes; // Return extimate of required bytes.\r
+}\r
+\r
+/* Determine the number of bytes needed to represent a Wide character string\r
+ as a MBCS string of given maximum length. Will optionally return the number\r
+ of wide characters that would be consumed.\r
+\r
+ A single wide character may convert into a one, two, three, or four byte\r
+ narrow (MBCS or UTF-8) character. The number of MBCS bytes can be determined\r
+ as follows.\r
+\r
+ If WCS char < 0x00000080 One Byte\r
+ Else if WCS char < 0x00000800 Two Bytes\r
+ Else if WCS char < 0x00010000 Three Bytes\r
+ Else Four Bytes\r
+\r
+ Since UEFI only supports the Unicode Base Multilingual Plane (BMP),\r
+ Four-byte characters should not be encountered.\r
+\r
+ @param[in] Src Pointer to a wide character string.\r
+ @param[in] Limit Maximum number of bytes the converted string may occupy.\r
+ @param[out] NumChar Pointer to where to store the number of wide characters, or NULL.\r
+\r
+ @return The number of bytes required to convert Src to MBCS,\r
+ not including the terminating NUL. If NumChar is not NULL, the number\r
+ of characters represented by the return value will be written to\r
+ where it points.\r
+*/\r
+size_t\r
+EFIAPI\r
+EstimateWtoM(const wchar_t * Src, size_t Limit, size_t *NumChar)\r
+{\r
+ ssize_t Estimate;\r
+ size_t CharCount;\r
+ ssize_t NumBytes;\r
+ wchar_t EChar;\r
+\r
+ Estimate = 0;\r
+ CharCount = 0;\r
+ EChar = *Src++; // Get the initial character and point to next\r
+ while(((NumBytes = OneWcToMcLen(EChar)) > 0) &&\r
+ ((size_t)(Estimate + NumBytes) < Limit))\r
+ { // Until one of the source characters is NUL\r
+ ++CharCount; // Count this character.\r
+ Estimate += NumBytes; // Count the Bytes for this character\r
+ EChar = *Src++; // Get the next source character and point to the next.\r
+ }\r
+ if(NumChar != NULL) {\r
+ *NumChar = CharCount;\r
+ }\r
+ return (size_t)Estimate; // Return esimate of required bytes.\r
+}\r
+\r
+/* Determine the number of characters in a MBCS string.\r
+ MBCS characters are one to four bytes long. By examining the first byte\r
+ of a MBCS character, one can determine the number of bytes comprising the\r
+ character.\r
+\r
+ 0x00 - 0x7F One\r
+ 0xC0 - 0xDF Two\r
+ 0xE0 - 0xEF Three\r
+ 0xF0 - 0xF7 Four\r
+\r
+ Since UEFI only supports the Unicode Base Multilingual Plane (BMP),\r
+ Four-byte characters should not be encountered.\r
+\r
+ @param[in] Src The string to examine\r
+\r
+ @return The number of characters represented by the MBCS string.\r
+**/\r
+size_t\r
+EFIAPI\r
+CountMbcsChars(const char *Src)\r
+{\r
+ size_t Count;\r
+ char EChar;\r
+\r
+ Count = 0;\r
+ EChar = *Src++;\r
+ while(EChar != 0) {\r
+ if(EChar < 0x80) {\r
+ ++Count;\r
+ }\r
+ else if(EChar < 0xE0) {\r
+ Count += 2;\r
+ ++Src;\r
+ }\r
+ else if(EChar < 0xF0) {\r
+ Count += 3;\r
+ Src += 2;\r
+ }\r
+ else {\r
+ // Ill-formed character\r
+ break;\r
+ }\r
+ }\r
+ return Count;\r
+}\r
+\r
+/** Convert a wide character (UTF16) into a multibyte character (UTF8)\r
+\r
+ Converts a wide character into a corresponding multibyte character that\r
+ begins in the conversion state described by the object pointed to by ps.\r
+ If dst is not a null pointer, the converted character is then stored into\r
+ the array pointed to by dst.\r
+\r
+ It is the caller's responsibility to ensure that Dest is large enough to\r
+ hold the resulting MBCS sequence.\r