AM Daemon ライブラリリファレンス
WinEncoding.h
[詳解]
1 /// @file
2 /// @brief Windows環境に特化した文字コード変換処理を提供する静的クラス WinEncoding のヘッダ。
3 ///
4 /// Copyright(C)SEGA
5 
6 #ifndef AMDAEMON_UTIL_WINENCODING_H
7 #define AMDAEMON_UTIL_WINENCODING_H
8 
9 #include "amdaemon/env.h"
10 
11 #include <string>
12 #include <cstdint>
13 #include <cstdlib>
14 
15 namespace amdaemon
16 {
17 namespace util
18 {
19 /// @addtogroup g_util
20 /// @{
21 
22  //--------------------
23  // WinEncoding クラス定義
24  //--------------------
25 
26  /// @brief Windows環境に特化した文字コード変換処理を提供する静的クラス。
27  /// @see Encoding
28  ///
29  /// 下記の Windows API 関数を用いた、
30  /// ANSI文字列とワイド文字列との間の文字コード変換処理を提供する。
31  ///
32  /// - MultiByteToWideChar
33  /// - WideCharToMultiByte
34  ///
35  /// ANSI文字列とは、ここでは char の配列で表す文字列全般を指す。
36  /// ワイド文字列とは、 wchar_t の配列で表す文字列を指す。
37  /// Windows環境においてワイド文字列の文字コードはUTF-16LEである。
38  ///
39  /// 静的メンバ関数 convert は、第1引数にコードページ値または変換種別タグ、
40  /// 第2引数に変換元文字列を渡すことで文字コード変換を行う。
41  /// マルチバイト文字列(CP932)とワイド文字列との間の変換については、
42  /// コードページ値や変換種別タグの指定が不要なオーバロードも定義される。
43  ///
44  /// @code
45  /// // ワイド文字列の L"あいうえお" をマルチバイト文字列化する
46  /// std::string aiueo = WinEncoding::convert(WinEncoding::CodePageMbcs, L"あいうえお");
47  ///
48  /// // マルチバイト文字列(CP932)の "あいうえお" をUTF-8化する
49  /// std::string u8aiueo = WinEncoding::convert(WinEncoding::MbcsToUtf8, "あいうえお");
50  ///
51  /// // マルチバイト文字列(CP932)の "あいうえお" をワイド文字列化する
52  /// // コードページ値や変換種別タグを指定不要なオーバロード
53  /// std::wstring w_aiueo = Encoding::convert("あいうえお");
54  /// @endcode
55  ///
56  /// また、主要な文字コード用にラップ関数が用意されている。
57  ///
58  /// @code
59  /// // マルチバイト文字列(CP932)の "あいうえお" をUTF-8化する
60  /// std::string u8aiueo = WinEncoding::convertMbcsToUtf8("あいうえお");
61  /// @endcode
62  ///
63  /// 文字コード変換における挙動は先述の Windows API に依存する。
64  /// 変換できない文字が含まれていてもその文字を '?' 等に置換するのみであり、
65  /// 変換処理を打ち切ることはない。
66  ///
67  /// @par マルチバイト文字列(CP932)へ変換する場合の特殊処理
68  /// このクラスの特殊な動作として、文字コード変換先がマルチバイト文字列(CP932)である場合、
69  /// 文字コード変換処理を行う前に、いくつかの文字について置換処理を行う。
70  /// 処理の内容は静的メンバ関数 #remapSjisToMbcs に準ずる。
71  /// @par
72  /// 各メンバ関数の引数 remappingSjisToMbcs に false を指定するとこの処理を無効化できる。
73  /// 引数指定を省略した場合は true を指定したものとして扱われる。
74  /// @par
75  /// この文字置換処理は、変換元の文字列がシフトJISから変換されていた場合であっても
76  /// 極力マルチバイト文字列(CP932)へ変換できるようにするためのものであり、
77  /// 変換先がマルチバイト文字列(CP932)でなければ行われない。
78  /// 変換先がマルチバイト文字列(CP932)ではない関数についても引数
79  /// remappingSjisToMbcs が存在するが、その場合の引数値は単に無視される。
81  {
82  public:
83  /// @brief マルチバイト文字列(CP932)のコードページ値 932 。
84  ///
85  /// CP932は、日本語WindowsではシフトJISと呼ばれることも多い文字コードである。
86  /// 本来のシフトJISより文字数が多く、一部文字の定義が異なる。
87  static const std::uint32_t CodePageMbcs = 932;
88 
89  /// UTF-8のコードページ値 65001 。
90  static const std::uint32_t CodePageUtf8 = 65001;
91 
92  /// ASCIIのコードページ値 1252 。
93  static const std::uint32_t CodePageAscii = 1252;
94 
95  /// マルチバイト文字列(CP932)からワイド文字列(UTF-16LE)への変換を示すタグ構造体。
96  struct MbcsToWideTag { };
97  /// マルチバイト文字列(CP932)からワイド文字列への変換を示すタグ。
98  static const MbcsToWideTag MbcsToWide;
99 
100  /// ワイド文字列からマルチバイト文字列(CP932)への変換を示すタグ構造体。
101  struct WideToMbcsTag { };
102  /// ワイド文字列からマルチバイト文字列(CP932)への変換を示すタグ。
103  static const WideToMbcsTag WideToMbcs;
104 
105  /// UTF-8文字列からワイド文字列への変換を示すタグ構造体。
106  struct Utf8ToWideTag { };
107  /// UTF-8文字列からワイド文字列への変換を示すタグ。
108  static const Utf8ToWideTag Utf8ToWide;
109 
110  /// ワイド文字列からUTF-8文字列への変換を示すタグ構造体。
111  struct WideToUtf8Tag { };
112  /// ワイド文字列からUTF-8文字列への変換を示すタグ。
113  static const WideToUtf8Tag WideToUtf8;
114 
115  /// マルチバイト文字列(CP932)からUTF-8文字列への変換を示すタグ構造体。
116  struct MbcsToUtf8Tag { };
117  /// マルチバイト文字列(CP932)からUTF-8文字列への変換を示すタグ。
118  static const MbcsToUtf8Tag MbcsToUtf8;
119 
120  /// UTF-8文字列からマルチバイト文字列(CP932)への変換を示すタグ構造体。
121  struct Utf8ToMbcsTag { };
122  /// UTF-8文字列からマルチバイト文字列(CP932)への変換を示すタグ。
123  static const Utf8ToMbcsTag Utf8ToMbcs;
124 
125  /// @brief ANSI文字列をワイド文字列に変換する。
126  /// @param[in] codePage 変換元のコードページ値。
127  /// @param[in] src ANSI文字列。
128  /// @param[in] remappingSjisToMbcs このオーバロードでは無視される。
129  /// @return ワイド文字列。
130  ///
131  /// 対象のコードページから変換できない文字は代替文字に置き換えられる。
132  static std::wstring convert(
133  std::uint32_t codePage,
134  const std::string& src,
135  bool remappingSjisToMbcs = true);
136 
137  /// @brief ワイド文字列をANSI文字列に変換する。
138  /// @param[in] codePage 変換先のコードページ値。
139  /// @param[in] src ワイド文字列。
140  /// @param[in] remappingSjisToMbcs
141  /// 引数 codePage の値が #CodePageMbcs である場合に、
142  /// 静的メンバ関数 #remapSjisToMbcs 相当の文字置換処理を事前に行うならば true 。
143  /// @return ANSI文字列。
144  ///
145  /// 対象のコードページに変換できない文字は代替文字 '?' に置き換えられる。
146  static std::string convert(
147  std::uint32_t codePage,
148  const std::wstring& src,
149  bool remappingSjisToMbcs = true);
150 
151  /// @brief マルチバイト文字列(CP932)をワイド文字列に変換する。
152  /// @param[in] src マルチバイト文字列(CP932)。
153  /// @param[in] remappingSjisToMbcs このオーバロードでは無視される。
154  /// @return ワイド文字列。
155  ///
156  /// 変換できない文字は代替文字に置き換えられる。
157  static std::wstring convert(const std::string& src, bool remappingSjisToMbcs = true)
158  {
159  return convert(CodePageMbcs, src, remappingSjisToMbcs);
160  }
161 
162  /// @brief ワイド文字列をマルチバイト文字列(CP932)に変換する。
163  /// @param[in] src ワイド文字列。
164  /// @param[in] remappingSjisToMbcs
165  /// 静的メンバ関数 #remapSjisToMbcs 相当の文字置換処理を事前に行うならば true 。
166  /// @return マルチバイト文字列(CP932)。
167  ///
168  /// 変換できない文字は代替文字 '?' に置き換えられる。
169  static std::string convert(const std::wstring& src, bool remappingSjisToMbcs = true)
170  {
171  return convert(CodePageMbcs, src, remappingSjisToMbcs);
172  }
173 
174  /// @brief マルチバイト文字列(CP932)をワイド文字列に変換する。
175  /// @param[in] tag 変換種別タグ。
176  /// @param[in] src マルチバイト文字列(CP932)。
177  /// @param[in] remappingSjisToMbcs このオーバロードでは無視される。
178  /// @return ワイド文字列。
179  ///
180  /// 変換できない文字は代替文字に置き換えられる。
181  inline static std::wstring convert(
182  MbcsToWideTag tag,
183  const std::string& src,
184  bool remappingSjisToMbcs = true);
185 
186  /// @brief マルチバイト文字列(CP932)をワイド文字列に変換する。
187  /// @param[in] src マルチバイト文字列(CP932)。
188  /// @return ワイド文字列。
189  ///
190  /// 変換できない文字は代替文字に置き換えられる。
191  static std::wstring convertMbcsToWide(const std::string& src)
192  {
193  return convert(MbcsToWide, src);
194  }
195 
196  /// @brief ワイド文字列をマルチバイト文字列(CP932)に変換する。
197  /// @param[in] tag 変換種別タグ。
198  /// @param[in] src ワイド文字列。
199  /// @param[in] remappingSjisToMbcs
200  /// 静的メンバ関数 #remapSjisToMbcs 相当の文字置換処理を事前に行うならば true 。
201  /// @return マルチバイト文字列(CP932)。
202  ///
203  /// 変換できない文字は代替文字 '?' に置き換えられる。
204  inline static std::string convert(
205  WideToMbcsTag tag,
206  const std::wstring& src,
207  bool remappingSjisToMbcs = true);
208 
209  /// @brief ワイド文字列をマルチバイト文字列(CP932)に変換する。
210  /// @param[in] src ワイド文字列。
211  /// @param[in] remappingSjisToMbcs
212  /// 静的メンバ関数 #remapSjisToMbcs 相当の文字置換処理を事前に行うならば true 。
213  /// @return マルチバイト文字列(CP932)。
214  ///
215  /// 変換できない文字は代替文字 '?' に置き換えられる。
216  static std::string convertWideToMbcs(
217  const std::wstring& src,
218  bool remappingSjisToMbcs = true)
219  {
220  return convert(WideToMbcs, src, remappingSjisToMbcs);
221  }
222 
223  /// @brief UTF-8文字列をワイド文字列に変換する。
224  /// @param[in] tag 変換種別タグ。
225  /// @param[in] src UTF-8文字列。
226  /// @param[in] remappingSjisToMbcs このオーバロードでは無視される。
227  /// @return ワイド文字列。
228  ///
229  /// 変換できない文字は代替文字に置き換えられる。
230  inline static std::wstring convert(
231  Utf8ToWideTag tag,
232  const std::string& src,
233  bool remappingSjisToMbcs = true);
234 
235  /// @brief UTF-8文字列をワイド文字列に変換する。
236  /// @param[in] src UTF-8文字列。
237  /// @return ワイド文字列。
238  ///
239  /// 変換できない文字は代替文字に置き換えられる。
240  static std::wstring convertUtf8ToWide(const std::string& src)
241  {
242  return convert(Utf8ToWide, src);
243  }
244 
245  /// @brief ワイド文字列をUTF-8文字列に変換する。
246  /// @param[in] tag 変換種別タグ。
247  /// @param[in] src ワイド文字列。
248  /// @param[in] remappingSjisToMbcs このオーバロードでは無視される。
249  /// @return UTF-8文字列。
250  ///
251  /// 変換できない文字は代替文字 '?' に置き換えられる。
252  inline static std::string convert(
253  WideToUtf8Tag tag,
254  const std::wstring& src,
255  bool remappingSjisToMbcs = true);
256 
257  /// @brief ワイド文字列をUTF-8文字列に変換する。
258  /// @param[in] src ワイド文字列。
259  /// @return UTF-8文字列。
260  ///
261  /// 変換できない文字は代替文字 '?' に置き換えられる。
262  static std::string convertWideToUtf8(const std::wstring& src)
263  {
264  return convert(WideToUtf8, src);
265  }
266 
267  /// @brief マルチバイト文字列(CP932)をUTF-8文字列に変換する。
268  /// @param[in] tag 変換種別タグ。
269  /// @param[in] src マルチバイト文字列(CP932)。
270  /// @param[in] remappingSjisToMbcs このオーバロードでは無視される。
271  /// @return UTF-8文字列。
272  ///
273  /// 変換できない文字は代替文字 '?' に置き換えられる。
274  inline static std::string convert(
275  MbcsToUtf8Tag tag,
276  const std::string& src,
277  bool remappingSjisToMbcs = true);
278 
279  /// @brief マルチバイト文字列(CP932)をUTF-8文字列に変換する。
280  /// @param[in] src マルチバイト文字列(CP932)。
281  /// @return UTF-8文字列。
282  ///
283  /// 変換できない文字は代替文字 '?' に置き換えられる。
284  static std::string convertMbcsToUtf8(const std::string& src)
285  {
286  return convert(MbcsToUtf8, src);
287  }
288 
289  /// @brief UTF-8文字列をマルチバイト文字列(CP932)に変換する。
290  /// @param[in] tag 変換種別タグ。
291  /// @param[in] src UTF-8文字列。
292  /// @param[in] remappingSjisToMbcs
293  /// 静的メンバ関数 #remapSjisToMbcs 相当の文字置換処理を事前に行うならば true 。
294  /// @return マルチバイト文字列(CP932)。
295  ///
296  /// 変換できない文字は代替文字 '?' に置き換えられる。
297  inline static std::string convert(
298  Utf8ToMbcsTag tag,
299  const std::string& src,
300  bool remappingSjisToMbcs = true);
301 
302  /// @brief UTF-8文字列をマルチバイト文字列(CP932)に変換する。
303  /// @param[in] src UTF-8文字列。
304  /// @param[in] remappingSjisToMbcs
305  /// 静的メンバ関数 #remapSjisToMbcs 相当の文字置換処理を事前に行うならば true 。
306  /// @return マルチバイト文字列(CP932)。
307  ///
308  /// 変換できない文字は代替文字 '?' に置き換えられる。
309  static std::string convertUtf8ToMbcs(
310  const std::string& src,
311  bool remappingSjisToMbcs = true)
312  {
313  return convert(Utf8ToMbcs, src, remappingSjisToMbcs);
314  }
315 
316  /// @brief
317  /// 本来のシフトJISとCP932との間でマッピングの異なるワイド文字について、
318  /// CP932への文字コード変換用に再マッピングする。
319  /// @param[in,out] target 再マッピング対象のワイド文字列。
320  /// @param[in] length
321  /// 再マッピング対象文字数。
322  /// 既定値 SIZE_MAX の場合は文字 '¥0' の直前までを対象とする。
323  /// @return target 自身。
324  /// @see remapSjisToMbcs(std::wstring&, std::size_t)
325  ///
326  /// 各文字に対して下記の置換処理を行う。
327  ///
328  /// - 文字 0x2014 ならば文字 0x2015 (―)に置換する。
329  /// - 文字 0x301C ならば文字 0xFF5E (〜)に置換する。
330  /// - 文字 0x2016 ならば文字 0x2225 (‖)に置換する。
331  /// - 文字 0x2212 ならば文字 0xFF0D (−)に置換する。
332  /// - 文字 0x00A2 ならば文字 0xFFE0 (¢)に置換する。
333  /// - 文字 0x00A3 ならば文字 0xFFE1 (£)に置換する。
334  /// - 文字 0x00AC ならば文字 0xFFE2 (¬)に置換する。
335  ///
336  /// ただし引数 target が nullptr である場合は何もせず nullptr を返す。
337  static wchar_t* remapSjisToMbcs(wchar_t* target, std::size_t length = SIZE_MAX);
338 
339  /// @brief
340  /// 本来のシフトJISとCP932との間でマッピングの異なるワイド文字について、
341  /// CP932への文字コード変換用に再マッピングする。
342  /// @param[in,out] target 再マッピング対象のワイド文字列。
343  /// @param[in] length
344  /// 再マッピング対象文字数。
345  /// この値と target.size() のうち小さい方の値を用いる。
346  /// @return target 自身の参照。
347  /// @see remapSjisToMbcs(wchar_t*, std::size_t)
348  ///
349  /// 各文字に対して下記の置換処理を行う。
350  ///
351  /// - 文字 0x2014 ならば文字 0x2015 (―)に置換する。
352  /// - 文字 0x301C ならば文字 0xFF5E (〜)に置換する。
353  /// - 文字 0x2016 ならば文字 0x2225 (‖)に置換する。
354  /// - 文字 0x2212 ならば文字 0xFF0D (−)に置換する。
355  /// - 文字 0x00A2 ならば文字 0xFFE0 (¢)に置換する。
356  /// - 文字 0x00A3 ならば文字 0xFFE1 (£)に置換する。
357  /// - 文字 0x00AC ならば文字 0xFFE2 (¬)に置換する。
358  static std::wstring& remapSjisToMbcs(
359  std::wstring& target,
360  std::size_t length = SIZE_MAX)
361  {
362  // std::min のためだけに algorithm ヘッダをインクルードしたくないので自前判定
364  &target.front(),
365  (length < target.size()) ? length : target.size());
366  return target;
367  }
368 
369  private:
370  // インスタンス化禁止
371  WinEncoding(); // 宣言のみ
372  WinEncoding(WinEncoding&); // 宣言のみ
373  WinEncoding& operator=(const WinEncoding&); // 宣言のみ
374  };
375 
376 /// @}
377 
378  //--------------------
379  // インラインメンバ関数実装
380  //--------------------
381 
382  // [static] マルチバイト文字列(CP932)をワイド文字列に変換する。
383  inline std::wstring WinEncoding::convert(
384  MbcsToWideTag /*tag*/,
385  const std::string& src,
386  bool remappingSjisToMbcs)
387  {
388  return convert(CodePageMbcs, src, remappingSjisToMbcs);
389  }
390 
391  // [static] ワイド文字列をマルチバイト文字列(CP932)に変換する。
392  inline std::string WinEncoding::convert(
393  WideToMbcsTag /*tag*/,
394  const std::wstring& src,
395  bool remappingSjisToMbcs)
396  {
397  return convert(CodePageMbcs, src, remappingSjisToMbcs);
398  }
399 
400  // [static] UTF-8文字列をワイド文字列に変換する。
401  inline std::wstring WinEncoding::convert(
402  Utf8ToWideTag /*tag*/,
403  const std::string& src,
404  bool remappingSjisToMbcs)
405  {
406  return convert(CodePageUtf8, src, remappingSjisToMbcs);
407  }
408 
409  // [static] ワイド文字列をUTF-8文字列に変換する。
410  inline std::string WinEncoding::convert(
411  WideToUtf8Tag /*tag*/,
412  const std::wstring& src,
413  bool remappingSjisToMbcs)
414  {
415  return convert(CodePageUtf8, src, remappingSjisToMbcs);
416  }
417 
418  // [static] マルチバイト文字列(CP932)をUTF-8文字列に変換する。
419  inline std::string WinEncoding::convert(
420  MbcsToUtf8Tag /*tag*/,
421  const std::string& src,
422  bool remappingSjisToMbcs)
423  {
424  return
425  convert(
426  CodePageUtf8,
427  convert(CodePageMbcs, src, remappingSjisToMbcs),
428  remappingSjisToMbcs);
429  }
430 
431  // [static] UTF-8文字列をマルチバイト文字列(CP932)に変換する。
432  inline std::string WinEncoding::convert(
433  Utf8ToMbcsTag /*tag*/,
434  const std::string& src,
435  bool remappingSjisToMbcs)
436  {
437  return
438  convert(
439  CodePageMbcs,
440  convert(CodePageUtf8, src, remappingSjisToMbcs),
441  remappingSjisToMbcs);
442  }
443 } // namespace util
444 } // namespace amdaemon
445 
446 #endif // AMDAEMON_UTIL_WINENCODING_H
static std::string convertWideToUtf8(const std::wstring &src)
ワイド文字列をUTF-8文字列に変換する。
Definition: WinEncoding.h:262
UTF-8文字列からワイド文字列への変換を示すタグ構造体。
Definition: WinEncoding.h:106
static const std::uint32_t CodePageUtf8
UTF-8のコードページ値 65001 。
Definition: WinEncoding.h:90
static const WideToUtf8Tag WideToUtf8
ワイド文字列からUTF-8文字列への変換を示すタグ。
Definition: WinEncoding.h:113
static std::string convertMbcsToUtf8(const std::string &src)
マルチバイト文字列(CP932)をUTF-8文字列に変換する。
Definition: WinEncoding.h:284
Daemonライブラリの環境定義を行うヘッダ。
static const Utf8ToWideTag Utf8ToWide
UTF-8文字列からワイド文字列への変換を示すタグ。
Definition: WinEncoding.h:108
static std::wstring & remapSjisToMbcs(std::wstring &target, std::size_t length=SIZE_MAX)
本来のシフトJISとCP932との間でマッピングの異なるワイド文字について、 CP932への文字コード変換用に再マ?...
Definition: WinEncoding.h:358
static const MbcsToUtf8Tag MbcsToUtf8
マルチバイト文字列(CP932)からUTF-8文字列への変換を示すタグ。
Definition: WinEncoding.h:118
AM Daemon ライブラリクラス群の基底名前空間。
Definition: Log.h:13
static std::wstring convert(const std::string &src, bool remappingSjisToMbcs=true)
マルチバイト文字列(CP932)をワイド文字列に変換する。
Definition: WinEncoding.h:157
ワイド文字列からマルチバイト文字列(CP932)への変換を示すタグ構造体。
Definition: WinEncoding.h:101
Windows環境に特化した文字コード変換処理を提供する静的クラス。
Definition: WinEncoding.h:80
マルチバイト文字列(CP932)からUTF-8文字列への変換を示すタグ構造体。
Definition: WinEncoding.h:116
static const Utf8ToMbcsTag Utf8ToMbcs
UTF-8文字列からマルチバイト文字列(CP932)への変換を示すタグ。
Definition: WinEncoding.h:123
UTF-8文字列からマルチバイト文字列(CP932)への変換を示すタグ構造体。
Definition: WinEncoding.h:121
static const std::uint32_t CodePageMbcs
マルチバイト文字列(CP932)のコードページ値 932 。
Definition: WinEncoding.h:87
マルチバイト文字列(CP932)からワイド文字列(UTF-16LE)への変換を示すタグ構造体。
Definition: WinEncoding.h:96
static std::wstring convert(std::uint32_t codePage, const std::string &src, bool remappingSjisToMbcs=true)
ANSI文字列をワイド文字列に変換する。
static std::string convertUtf8ToMbcs(const std::string &src, bool remappingSjisToMbcs=true)
UTF-8文字列をマルチバイト文字列(CP932)に変換する。
Definition: WinEncoding.h:309
static std::string convertWideToMbcs(const std::wstring &src, bool remappingSjisToMbcs=true)
ワイド文字列をマルチバイト文字列(CP932)に変換する。
Definition: WinEncoding.h:216
static const WideToMbcsTag WideToMbcs
ワイド文字列からマルチバイト文字列(CP932)への変換を示すタグ。
Definition: WinEncoding.h:103
static std::wstring convertMbcsToWide(const std::string &src)
マルチバイト文字列(CP932)をワイド文字列に変換する。
Definition: WinEncoding.h:191
static std::string convert(const std::wstring &src, bool remappingSjisToMbcs=true)
ワイド文字列をマルチバイト文字列(CP932)に変換する。
Definition: WinEncoding.h:169
static const MbcsToWideTag MbcsToWide
マルチバイト文字列(CP932)からワイド文字列への変換を示すタグ。
Definition: WinEncoding.h:98
ワイド文字列からUTF-8文字列への変換を示すタグ構造体。
Definition: WinEncoding.h:111
static wchar_t * remapSjisToMbcs(wchar_t *target, std::size_t length=SIZE_MAX)
本来のシフトJISとCP932との間でマッピングの異なるワイド文字について、 CP932への文字コード変換用に再マ?...
static std::wstring convertUtf8ToWide(const std::string &src)
UTF-8文字列をワイド文字列に変換する。
Definition: WinEncoding.h:240
static const std::uint32_t CodePageAscii
ASCIIのコードページ値 1252 。
Definition: WinEncoding.h:93