001    /*
002     * Copyright (c) 2009 The openGion Project.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
013     * either express or implied. See the License for the specific language
014     * governing permissions and limitations under the License.
015     */
016    package org.opengion.fukurou.mail;
017    
018    // import java.io.InputStream;
019    // import java.io.OutputStream;
020    // import java.io.ByteArrayOutputStream;
021    // import java.io.ByteArrayInputStream;
022    import java.io.UnsupportedEncodingException;
023    // import java.io.IOException;
024    
025    // import javax.activation.DataHandler;
026    // import javax.activation.DataSource;
027    import javax.mail.internet.InternetAddress;
028    import javax.mail.internet.MimeMessage;
029    // import javax.mail.internet.MimeUtility;
030    import javax.mail.MessagingException;
031    // import com.sun.mail.util.BASE64EncoderStream;
032    
033    // import java.nio.charset.Charset;             // 5.5.2.6 (2012/05/25)
034    
035    /**
036     * MailCharset は、E-Mail 送信時?エンコードに応じた??行う為の?
037     * インターフェースです?
038     *
039     * E-Mail で日本語を送信する場合?ISO-2022-JP(JISコー?化して?bit で
040     * エンコードして送信する?がありますが、Windows系の特殊文字や、unicodeと
041     * ??マッピングが異なる文字などが??化けします?
042     * 対応方法としては?
043     * 『1.Windows-31J + 8bit 送信?
044     * 『2.ISO-2022-JP に独自変換 + 7bit 送信?
045     * の方法があります?
046     * 今回、この?つの方法につ?、それぞれサブクラス化を行い、??きるように
047     * したのが?こ?インターフェース、およ?、サブクラスです?
048     *
049     * 『1.Windows-31J + 8bit 送信』?方法???常の JavaMail API に準拠して
050     * 処?行う、Mail_Windows31J_Charset サブクラスで実?て?す?
051     * 古?イラーおよび、古?ールサーバ?ではメール転送できな??
052     * こ?方式?、社?使用する場合?みに、利用できますが、主としてWindows系の
053     * 社?ス?においては、こちら?方が?なにかとトラブルは少な?思います?
054     *
055     * 『2.ISO-2022-JP に独自変換 + 7bit 送信』?実???
056     * JAVA PRESS Vol.37 (http://www.gihyo.co.jp/magazines/javapress)の
057     * 【特??決定版??サーバサイドJavaの日本語??
058     *  第3?JavaMailの日本語???ログラミング……木下信
059     *“?ルチ?ラ?フォー??な日本語メール送信?完?解説
060     * でのサンプルアプリケーション
061     * http://www.gihyo.co.jp/book/2004/225371/download/toku1_3.zip
062     * を?使用して、Mail_ISO2022JP_Charset サブクラスで実?て?す?
063     *
064     * これら?サブクラスは、MailCharsetFactory ファクトリクラスより、作?されます?
065     * そ?場合?引数のキャラクタセ?名?、Windows-31J 、MS932 か?それ以外となって?す?
066     * それ以外が?された場合?、ISO-2022-JP を使用します?
067     *
068     * @version  4.0
069     * @author   Kazuhiko Hasegawa
070     * @since    JDK5.0,
071     */
072    public interface MailCharset {
073    
074            /**
075             * ?ストをセ?します?
076             * Part#setText() の代わりにこちらを使??します?
077             *
078             * ※ ?で、MessagingException が発生した?合?、RuntimeException に変換されて throw されます?
079             *
080             * @param mimeMsg MimeMessage?取り込み件数
081             * @param text    設定するテキス?
082             */
083            void setTextContent( MimeMessage mimeMsg, String text ) ;
084    
085            /**
086             * 日本語を含???用?ストを生?します?
087             * 変換結果は ASCII なので、これをそ?まま setSubject ?InternetAddress
088             * のパラメタとして使用してください?
089             *
090             * ※ ?で、UnsupportedEncodingException が発生した?合?、RuntimeException に変換されて throw されます?
091             *
092             * @param text    設定するテキス?
093             *
094             * @return      日本語を含???用?ス?
095             */
096            String encodeWord( String text ) ;
097    
098            /**
099             * 日本語を含?ドレスを生成します?
100             * personal に、日本語が含まれると想定して?す?
101             * サブクラスで、日本語??行う場合?方法?、それぞれ異なります?
102             *
103             * ※ ?で、UnsupportedEncodingException が発生した?合?、RuntimeException に変換されて throw されます?
104             *
105             * @param address    アドレス部?
106             * @param personal   日本語?説明部?
107             *
108             * @return      日本語を含?ドレス
109             */
110            InternetAddress getAddress( String address,String personal ) ;
111    
112            /**
113             * Content-Transfer-Encoding を指定する?合? ビット数を返します?
114             *
115             * Windows系は?bit / ISO-2022-JP 系は?bit になります?
116             *
117             * @return      ビット数
118             */
119            String getBit() ;
120    }
121    
122    /**
123     * MailCharsetFactory は、MailCharset インターフェースを実?たサブクラス?
124     * 作?する ファクトリクラスです?
125     *
126     * 引数のキャラクタセ?名が、Windows-31J 、MS932 の場合??
127     * 『1.Windows-31J + 8bit 送信?の実?ある、Mail_Windows31J_Charset
128     * サブクラスを返します?
129     * それ以外が?された場合?、ISO-2022-JP を使用して、??.ISO-2022-JP に独自変換 + 7bit 送信?
130     * の実?ある、Mail_ISO2022JP_Charset サブクラスを返します?
131     *
132     * @version  4.0
133     * @author   Kazuhiko Hasegawa
134     * @since    JDK5.0,
135     */
136    //class MailCharsetFactory {
137    //
138    //      /**
139    //       * インスタンスの生?を抑止します?
140    //       */
141    //      private MailCharsetFactory() {
142    //              // 何もありません?PMD エラー回避)
143    //      }
144    //
145    //      /**
146    //       * キャラクタセ?に応じた?MailCharset オブジェクトを返します?
147    //       *
148    //       * Windows-31J 、MS932 、Shift_JIS の場合?、Mail_Windows31J_Charset
149    //       * そ?他?、ISO-2022-JP として、Mail_ISO2022JP_Charset を返します?
150    //       *
151    //       * 注意:null の場合?、デフォルトではなく?Mail_ISO2022JP_Charset を返します?
152    //       *
153    //       * @param  charset キャラクタセ?[Windows-31J/MS932/Shift_JIS/そ?他]
154    //       *
155    //       * @return MailCharset
156    //       */
157    //      static MailCharset newInstance( final String charset ) {
158    //              final MailCharset mcset;
159    //
160    //              if( "MS932".equalsIgnoreCase( charset ) ||
161    //                      "Shift_JIS".equalsIgnoreCase( charset ) ||
162    //                      "Windows-31J".equalsIgnoreCase( charset ) ) {
163    //                              mcset = new Mail_Windows31J_Charset( charset );
164    //              }
165    //              else {
166    //                      mcset = new Mail_ISO2022JP_Charset();
167    //              }
168    //              return mcset ;
169    //      }
170    //}
171    
172    /**
173     * MailCharset インターフェースを実??Windwos-31J エンコード時のサブクラスです?
174     *
175     * 『1.Windows-31J + 8bit 送信?の実?す?
176     *
177     * @version  4.0
178     * @author   Kazuhiko Hasegawa
179     * @since    JDK5.0,
180     */
181    //class Mail_Windows31J_Charset implements MailCharset {
182    //      private final String charset ;                  // "Windows-31J" or "MS932"
183    //
184    //      /**
185    //       * 引数に、エンコード方式を?して、作?するコンストラクタです?
186    //       *
187    //       * @param charset String
188    //       */
189    //      public Mail_Windows31J_Charset( final String charset ) {
190    //              this.charset = charset;
191    //      }
192    //
193    //      /**
194    //       * ?ストをセ?します?
195    //       * Part#setText() の代わりにこちらを使??します?
196    //       *
197    //       * @param mimeMsg MimeMessage
198    //       * @param text    String
199    //       * @throws RuntimeException(MessagingException)
200    //       */
201    //      public void setTextContent( final MimeMessage mimeMsg, final String text ) {
202    //              try {
203    //                      mimeMsg.setText( text,charset );                // "text/plain" Content
204    //              }
205    //              catch( MessagingException ex ) {
206    //                      String errMsg = "???ストをセ?できません?
207    //                                                              + "text=" + text + " , charset=" + charset ;
208    //                      throw new RuntimeException( errMsg,ex );
209    //              }
210    //      }
211    //
212    //      /**
213    //       * 日本語を含???用?ストを生?します?
214    //       * 変換結果は ASCII なので、これをそ?まま setSubject ?InternetAddress
215    //       * のパラメタとして使用してください?
216    //       *
217    //       * @param text    String
218    //       *
219    //       * @return      日本語を含???用?ス?
220    //       * @throws RuntimeException(UnsupportedEncodingException)
221    //       */
222    //      public String encodeWord( final String text ) {
223    //              try {
224    //                      return MimeUtility.encodeText( text, charset, "B" );
225    //              }
226    //              catch( UnsupportedEncodingException ex ) {
227    //                      String errMsg = "??エンコードが出来ません?
228    //                                                              + "text=" + text + " , charset=" + charset ;
229    //                      throw new RuntimeException( errMsg,ex );
230    //              }
231    //      }
232    //
233    //      /**
234    //       * 日本語を含?ドレスを生成します?
235    //       * personal に、日本語が含まれると想定して?す?
236    //       * サブクラスで、日本語??行う場合?方法?、それぞれ異なります?
237    //       *
238    //       * @param address    String
239    //       * @param personal   String
240    //       *
241    //       * @return InternetAddress
242    //       * @throws RuntimeException(UnsupportedEncodingException)
243    //       */
244    //      public InternetAddress getAddress( final String address,final String personal ) {
245    //              try {
246    //                      return new InternetAddress( address,personal,charset );
247    //              }
248    //              catch( UnsupportedEncodingException ex ) {
249    //                      String errMsg = "??エンコードが出来ません?
250    //                                                              + "address=" + address + " , charset=" + charset ;
251    //                      throw new RuntimeException( errMsg,ex );
252    //              }
253    //      }
254    //
255    //      /**
256    //       * Content-Transfer-Encoding を指定する?合? ビット数を返します?
257    //       *
258    //       * Windows系は?bit / ISO-2022-JP 系は?bit になります?
259    //       *
260    //       * @return      ビット数("8bit" 固?
261    //       */
262    //      public String getBit() {
263    //              return "8bit" ;
264    //      }
265    //}
266    
267    /**
268     * MailCharset インターフェースを実??ISO-2022-JP エンコード時のサブクラスです?
269     *
270     * 『2.ISO-2022-JP に独自変換 + 7bit 送信?の実?す?
271     *
272     * @version  4.0
273     * @author   Kazuhiko Hasegawa
274     * @since    JDK5.0,
275     */
276    //class Mail_ISO2022JP_Charset implements MailCharset {
277    //
278    //      /**
279    //       * プラ?フォー?存??ォルト? Charset です?
280    //       * プラ?フォー?存?を?慮する場合?エンコード指定で作?しておく事をお勧めします?
281    //       *
282    //       * @og.rev 5.5.2.6 (2012/05/25) findbugs対?
283    //       */
284    //      private static final Charset DEFAULT_CHARSET = Charset.defaultCharset() ;
285    //
286    //      /**
287    //       * ?ストをセ?します?
288    //       * Part#setText() の代わりにこちらを使??します?
289    //       *
290    //       * @param mimeMsg MimeMessage
291    //       * @param text    String
292    //       * @throws RuntimeException(MessagingException)
293    //       */
294    //      public void setTextContent( final MimeMessage mimeMsg, final String text ) {
295    //              try {
296    //                      // mimeMsg.setText(text, "ISO-2022-JP");
297    //                      mimeMsg.setDataHandler(new DataHandler(new JISDataSource(text)));
298    //              }
299    //              catch( MessagingException ex ) {
300    //                      String errMsg = "???ストをセ?できません?
301    //                                                              + "text=" + text ;
302    //                      throw new RuntimeException( errMsg,ex );
303    //              }
304    //      }
305    //
306    //      /**
307    //       * 日本語を含???用?ストを生?します?
308    //       * 変換結果は ASCII なので、これをそ?まま setSubject ?InternetAddress
309    //       * のパラメタとして使用してください?
310    //       *
311    //       * @param text    String
312    //       *
313    //       * @return      日本語を含???用?ス?
314    //       * @throws RuntimeException(UnsupportedEncodingException)
315    //       */
316    //      public String encodeWord( final String text ) {
317    //              try {
318    //                      return "=?ISO-2022-JP?B?" +
319    //                              new String(
320    //                                      BASE64EncoderStream.encode(
321    //                                              CharCodeConverter.sjisToJis(
322    //                                                      UnicodeCorrecter.correctToCP932(text).getBytes("Windows-31J")
323    //                                              )
324    //                                      )
325    //                              ,DEFAULT_CHARSET ) + "?=";              // 5.5.2.6 (2012/05/25) findbugs対?
326    //              }
327    //              catch( UnsupportedEncodingException ex ) {
328    //                      String errMsg = "??エンコードが出来ません?
329    //                                                              + "text=" + text + " , charset=Windows-31J" ;
330    //                      throw new RuntimeException( errMsg,ex );
331    //              }
332    //      }
333    //
334    //      /**
335    //       * 日本語を含?ドレスを生成します?
336    //       * personal に、日本語が含まれると想定して?す?
337    //       * サブクラスで、日本語??行う場合?方法?、それぞれ異なります?
338    //       *
339    //       * @param address    String
340    //       * @param personal   String
341    //       *
342    //       * @return InternetAddress
343    //       * @throws RuntimeException(UnsupportedEncodingException)
344    //       */
345    //      public InternetAddress getAddress( final String address,final String personal ) {
346    //              try {
347    //                      return new InternetAddress( address,encodeWord( personal ) );
348    //              }
349    //              catch( UnsupportedEncodingException ex ) {
350    //                      String errMsg = "??エンコードが出来ません?
351    //                                                              + "address=" + address ;
352    //                      throw new RuntimeException( errMsg,ex );
353    //              }
354    //      }
355    //
356    //      /**
357    //       * Content-Transfer-Encoding を指定する?合? ビット数を返します?
358    //       *
359    //       * Windows系は?bit / ISO-2022-JP 系は?bit になります?
360    //       *
361    //       * @return      ビット数("7bit" 固?
362    //       */
363    //      public String getBit() {
364    //              return "7bit" ;
365    //      }
366    //}
367    
368    /**
369     * ?スト?本?送信するための DataSource です?
370     *
371     * Windows-31J でバイトコードに変換した後?独自エンコードにて?
372     * Shift-JIS ?JIS 変換して?す?
373     *
374     * @version  4.0
375     * @author   Kazuhiko Hasegawa
376     * @since    JDK5.0,
377     */
378    //class JISDataSource implements DataSource {
379    //      private final byte[] data;
380    //
381    //      public JISDataSource( final String str ) {
382    //              try {
383    //                      data = CharCodeConverter.sjisToJis(
384    //                              UnicodeCorrecter.correctToCP932(str).getBytes("Windows-31J"));
385    //
386    //              } catch (UnsupportedEncodingException e) {
387    //                      String errMsg = "Windows-31J でのエンコー?ングが?来ません? + str;
388    //                      throw new RuntimeException( errMsg,e );
389    //              }
390    //      }
391    //
392    //      /**
393    //       * ??タの MIME タイプを??の形で返します?
394    //       * かならず有効なタイプを返すべきです?
395    //       * DataSource の実???タタイプを 決定できな??合??
396    //       * getContentType は "application/octet-stream" を返すこと?提案します?
397    //       *
398    //       * @return      MIME タイ?
399    //       */
400    //      public String getContentType() {
401    //              return "text/plain; charset=ISO-2022-JP";
402    //      }
403    //
404    //      /**
405    //       * ??タを表?InputStream を返します?
406    //       * それができな??合?適?例外をスローします?
407    //       *
408    //       * @return InputStream
409    //       * @throws IOException
410    //       */
411    //      public InputStream getInputStream() throws IOException {
412    //              return new ByteArrayInputStream( data );
413    //      }
414    //
415    //      /**
416    //       * ??タが書込可能な?OutputStream を返します?
417    //       * それができな??合?適?例外をスローします?
418    //       *
419    //       * ※ こ?クラスでは実?れて?せん?
420    //       *
421    //       * @return OutputStream
422    //       * @throws IOException
423    //       */
424    //      public OutputStream getOutputStream() throws IOException {
425    //              String errMsg = "こ?クラスでは実?れて?せん?;
426    //      //      throw new UnsupportedOperationException( errMsg );
427    //              throw new IOException( errMsg );
428    //      }
429    //
430    //      /**
431    //       * こ?オブジェクト? '名前' を返します?
432    //       * こ?名前は下層のオブジェクト?性質によります?
433    //       * ファイルをカプセル化す?DataSource な?オブジェクト?
434    //       * ファイル名を返すようにするかもしれません?
435    //       *
436    //       * @return      オブジェクト?名前
437    //       */
438    //      public String getName() {
439    //              return "JISDataSource";
440    //      }
441    //}
442    
443    /**
444     * ?関係?コンバ?タです?
445     * ?コード?オリジナルは<a href="http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/CCGI/kanjicod.html">Japanese Kanji Code</a>にて公開されて?も?です?
446     * また?http://www.sk-jp.com/cgi-bin/treebbs.cgi?kako=1&all=644&s=681
447     * にて YOSI さんが?開されたコードも参?にして??と?か実質同じで??
448     *
449     * @version  4.0
450     * @author   Kazuhiko Hasegawa
451     * @since    JDK5.0,
452     */
453    //class CharCodeConverter {
454    //      private static final byte[] SJIS_KANA;  // 5.1.9.0 (2010/09/01) public ?private へ変更
455    //
456    //      /**
457    //       * インスタンスの生?を抑止します?
458    //       */
459    //      private CharCodeConverter() {
460    //              // 何もありません?PMD エラー回避)
461    //      }
462    //
463    //      static {
464    //              try {
465    //                      // 全角への変換??ブル
466    //                      SJIS_KANA = "。?」?・ヲァィゥェォャュョ??アイウエオカキクケコサシスセソタチツ?ナニヌネノハヒフヘ?マミ?モヤユヨラリルレロワン゛?".getBytes("Shift_JIS");
467    //              } catch( UnsupportedEncodingException ex ) {
468    //                      throw new RuntimeException( "CANT HAPPEN",ex );
469    //              }
470    //      }
471    //
472    //      /**
473    //       * Shift_JIS エンコー?ングスキー?基づくバイト??
474    //       * ISO-2022-JP エンコー?ングスキー?変換します?
475    //       * 「半角カナ?は対応する?角文字に変換します?
476    //       *
477    //       * @param sjisBytes byte[] エンコードするShift_JISバイト??
478    //       *
479    //       * @return byte[] 変換後?ISO-2022-JP(JIS)バイト??not null)
480    //       */
481    //      public static byte[] sjisToJis( final byte[] sjisBytes ) {
482    //              ByteArrayOutputStream out = new ByteArrayOutputStream();
483    //              boolean nonAscii = false;
484    //              int len = sjisBytes.length;
485    //              for(int i = 0; i < len; i++ ) {
486    //                      if(sjisBytes[i] >= 0) {
487    //                              if(nonAscii) {
488    //                                      nonAscii = false;
489    //                                      out.write(0x1b);
490    //                                      out.write('(');
491    //                                      out.write('B');
492    //                              }
493    //                              out.write(sjisBytes[i]);
494    //                      } else {
495    //                              if(!nonAscii) {
496    //                                      nonAscii = true;
497    //                                      out.write(0x1b);
498    //                                      out.write('$');
499    //                                      out.write('B');
500    //                              }
501    //                              int bt = sjisBytes[i] & 0xff;
502    //                              if(bt >= 0xa1 && bt <= 0xdf) {
503    //                                      // 半角カナ?全角に変換
504    //                                      int kanaIndex = (bt - 0xA1) * 2;
505    //                                      sjisToJis(out, SJIS_KANA[kanaIndex], SJIS_KANA[kanaIndex + 1]);
506    //                              } else {
507    //                                      i++;
508    //                                      if(i == len) { break; }
509    //                                      sjisToJis(out, sjisBytes[i - 1], sjisBytes[i]);
510    //                              }
511    //                      }
512    //              }
513    //              if(nonAscii) {
514    //                      out.write(0x1b);
515    //                      out.write('(');
516    //                      out.write('B');
517    //              }
518    //              return out.toByteArray();
519    //      }
520    //
521    //      /**
522    //       * ?文字??バイ?Shift_JIS コードを JIS コードに変換して書き?します?
523    //       */
524    //      private static void sjisToJis(
525    //                              final ByteArrayOutputStream out, final byte bhi, final byte blo) {
526    //              int hi = (bhi << 1) & 0xFF;
527    //              int lo = blo & 0xFF;
528    //              if(lo < 0x9F) {
529    //                      if(hi < 0x3F) { hi += 0x1F; } else { hi -= 0x61; }
530    //                      if(lo > 0x7E) { lo -= 0x20; } else { lo -= 0x1F; }
531    //              } else {
532    //                      if(hi < 0x3F) { hi += 0x20; } else { hi -= 0x60; }
533    //                      lo -= 0x7E;
534    //              }
535    //              out.write(hi);
536    //              out.write(lo);
537    //      }
538    //}
539    
540    /**
541     * unicode と、JIS との?コード?関係で、変換して?す?
542     *
543     * 0x301c(&#x301c;) を?0xff5e(&#xff5e;) へ?
544     * 0x2016(&#x2016;) を?0x2225(&#x2225;) へ?
545     * 0x2212(&#x2212;) を?0xff0d(&#xff0d;) へ?
546     * それぞれコード変換します?
547     *
548     * @version  4.0
549     * @author   Kazuhiko Hasegawa
550     * @since    JDK5.0,
551     */
552    //class UnicodeCorrecter {
553    //
554    //      /**
555    //       * インスタンスの生?を抑止します?
556    //       */
557    //      private UnicodeCorrecter() {
558    //              // 何もありません?PMD エラー回避)
559    //      }
560    //
561    //      /**
562    //       * Unicode ??の補正を行います?
563    //       * "MS932" コンバ?タでエンコードしようとした際に
564    //       * 正常に変換できな??補正します?
565    //       */
566    //      public static String correctToCP932( final String str ) {
567    //              String rtn = "";
568    //
569    //              if( str != null ) {
570    //                      int cnt = str.length();
571    //                      StringBuilder buf = new StringBuilder( cnt );
572    //                      for(int i=0; i<cnt; i++) {
573    //                              buf.append(correctToCP932(str.charAt(i)));
574    //                      }
575    //                      rtn = buf.toString() ;
576    //              }
577    //              return rtn ;
578    //      }
579    //
580    //      /**
581    //       * キャラクタ単位に、Unicode ??の補正を行います?
582    //       *
583    //       * 風間殿のペ?ジを参?して?す?
584    //       * @see <a href="http://www.ingrid.org/java/i18n/encoding/ja-conv.html" target="_blank">
585    //       * http://www.ingrid.org/java/i18n/encoding/ja-conv.html</a>
586    //       */
587    //      public static char correctToCP932( final char ch ) {
588    //              char rtn = ch;
589    //
590    //              switch (ch) {
591    //      //              case 0x00a2:    return 0xffe0;          // ≪
592    //      //              case 0x00a3:    return 0xffe1;          // ?
593    //      //              case 0x00ac:    return 0xffe2;          // μ
594    //      //              case 0x03bc:    return 0x00b5;          // ・
595    //      //              case 0x2014:    return 0x2015;          // ??
596    //      //              case 0x2016:    return 0x2225;          // ≫
597    //      //              case 0x2212:    return 0xff0d;          // ?
598    //      //              case 0x226a:    return 0x00ab;          // ∥
599    //      //              case 0x226b:    return 0x00bb;          // ヴ
600    //      //              case 0x301c:    return 0xff5e;          // ??
601    //      //              case 0x30f4:    return 0x3094;          // ??
602    //      //              case 0x30fb:    return 0x00b7;          // ??
603    //      //              case 0xff0c:    return 0x00b8;          // ?
604    //      //              case 0xffe3:    return 0x00af;          // ?
605    //
606    //                      case 0x00a2:    rtn = 0xffe0; break;            // ??(1-81, CENT SIGN)
607    //                      case 0x00a3:    rtn = 0xffe1; break;            // ? (1-82, POUND SIGN)
608    //                      case 0x00a5:    rtn = 0x005c; break;            // \ (D/12, YEN SIGN)
609    //                      case 0x00ac:    rtn = 0xffe2; break;            // ? (2-44, NOT SIGN)
610    //                      case 0x2016:    rtn = 0x2225; break;            // ∥ (1-34, DOUBLE VERTICAL LINE)
611    //                      case 0x203e:    rtn = 0x007e; break;            // ~ (F/14, OVERLINE)
612    //                      case 0x2212:    rtn = 0xff0d; break;            // ??(1-61, MINUS SIGN)
613    //                      case 0x301c:    rtn = 0xff5e; break;            // ??(1-33, WAVE DASH)
614    //
615    //      //              case 0x301c:    return 0xff5e;
616    //      //              case 0x2016:    return 0x2225;
617    //      //              case 0x2212:    return 0xff0d;
618    //                      default:                break;                  // 4.0.0 (2005/01/31)
619    //              }
620    //              return rtn;
621    //      }
622    //}