1 // Written in the D programming language.
2 
3 /**
4  * Support UTF-8 on Windows 95, 98 and ME systems.
5  *
6  * Copyright: Copyright The D Language Foundation" 2005 - 2009.
7  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
8  * Authors:   $(HTTP digitalmars.com, Walter Bright)
9  */
10 /*          Copyright The D Language Foundation" 2005 - 2009.
11  * Distributed under the Boost Software License, Version 1.0.
12  *    (See accompanying file LICENSE_1_0.txt or copy at
13  *          http://www.boost.org/LICENSE_1_0.txt)
14  */
15 module std.windows.charset;
16 
17 version (StdDdoc)
18 {
19     /******************************************
20      * Converts the UTF-8 string s into a null-terminated string in a Windows
21      * 8-bit character set.
22      *
23      * Params:
24      * s = UTF-8 string to convert.
25      * codePage = is the number of the target codepage, or
26      *   0 - ANSI,
27      *   1 - OEM,
28      *   2 - Mac
29      *
30      * Authors:
31      *      yaneurao, Walter Bright, Stewart Gordon
32      */
33     const(char)* toMBSz(scope const(char)[] s, uint codePage = 0);
34 
35     /**********************************************
36      * Converts the null-terminated string s from a Windows 8-bit character set
37      * into a UTF-8 char array.
38      *
39      * Params:
40      * s = UTF-8 string to convert.
41      * codePage = is the number of the source codepage, or
42      *   0 - ANSI,
43      *   1 - OEM,
44      *   2 - Mac
45      * Authors: Stewart Gordon, Walter Bright
46      */
47     string fromMBSz(immutable(char)* s, int codePage = 0);
48 }
49 else:
50 
51 version (Windows):
52 
53 import core.sys.windows.winbase, core.sys.windows.winnls;
54 import std.conv;
55 import std.string;
56 import std.windows.syserror;
57 
58 import std.internal.cstring;
59 
60 const(char)* toMBSz(scope const(char)[] s, uint codePage = 0)
61 {
62     // Only need to do this if any chars have the high bit set
63     foreach (char c; s)
64     {
65         if (c >= 0x80)
66         {
67             char[] result;
68             int readLen;
69             auto wsTmp = s.tempCStringW();
70             result.length = WideCharToMultiByte(codePage, 0, wsTmp, -1, null, 0,
71                     null, null);
72 
73             if (result.length)
74             {
75                 readLen = WideCharToMultiByte(codePage, 0, wsTmp, -1, result.ptr,
76                         to!int(result.length), null, null);
77             }
78 
79             wenforce(readLen && readLen == result.length, "Couldn't convert string");
80             return result.ptr;
81         }
82     }
83     return std..string.toStringz(s);
84 }
85 
86 string fromMBSz(return scope immutable(char)* s, int codePage = 0)
87 {
88     const(char)* c;
89 
90     for (c = s; *c != 0; c++)
91     {
92         if (*c >= 0x80)
93         {
94             wchar[] result;
95             int readLen;
96 
97             result.length = MultiByteToWideChar(codePage, 0, s, -1, null, 0);
98 
99             if (result.length)
100             {
101                 readLen = MultiByteToWideChar(codePage, 0, s, -1, result.ptr,
102                         to!int(result.length));
103             }
104 
105             wenforce(readLen && readLen == result.length, "Couldn't convert string");
106 
107             return result[0 .. result.length-1].to!string; // omit trailing null
108         }
109     }
110     return s[0 .. c-s];         // string is ASCII, no conversion necessary
111 }