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 */
016package org.opengion.fukurou.util;
017
018/**
019 * unicode と JIS との文字コードの関係で変換しています。
020 * <pre>
021 * http://www.ingrid.org/java/i18n/encoding/ja-conv.html
022 *
023 * 0x00a2 ⇒ 0xffe0 ¢ (1-81, CENT SIGN)
024 * 0x00a3 ⇒ 0xffe1 £ (1-82, POUND SIGN)
025 * 0x00a5 ⇒ 0x005c \  (D/12, YEN SIGN)
026 * 0x00ac ⇒ 0xffe2 ¬ (2-44, NOT SIGN)
027 * 0x2016 ⇒ 0x2225 ∥ (1-34, DOUBLE VERTICAL LINE)
028 * 0x203e ⇒ 0x007e ~  (F/14, OVERLINE)
029 * 0x2212 ⇒ 0xff0d - (1-61, MINUS SIGN)
030 * 0x301c ⇒ 0xff5e ~ (1-33, WAVE DASH)
031 *
032 * それぞれコード変換します。
033 * </pre>
034 *
035 * @og.rev 5.9.3.3 (2015/12/26) fukurou.mailパッケージからutilに移動し、機能追加
036 *
037 * @version     4.0
038 * @author      Kazuhiko Hasegawa
039 * @since       JDK5.0,
040 */
041public final class UnicodeCorrecter {
042        // 8.5.4.2 (2024/01/12) PMD 7.0.0 UseShortArrayInitializer
043//      private static final String[] ENC_LIST = new String[] { "Shift_JIS" , "SJIS", "Windows-31J", "CP932", "MS932" };
044        private static final String[] ENC_LIST = { "Shift_JIS" , "SJIS", "Windows-31J", "CP932", "MS932" };
045
046        /**
047         * デフォルトコンストラクターをprivateにして、
048         * オブジェクトの生成をさせないようにする。
049         */
050        private UnicodeCorrecter() {
051                // 何もありません。(PMD エラー回避)
052        }
053
054        /**
055         * Unicode 文字列の補正を行います。
056         * "MS932" コンバータでエンコードしようとした際に
057         * 正常に変換できない部分を補正します。
058         *
059         * @param       str     入力文字列
060         * @return      Unicode文字列の補正結果
061         */
062        public static String correctToCP932( final String str ) {
063                String rtn = "";
064
065                if( str != null ) {
066                        final int cnt = str.length();
067                        final StringBuilder buf = new StringBuilder( cnt );
068                        for(int i=0; i<cnt; i++) {
069                                buf.append(correctToCP932(str.charAt(i)));
070                        }
071                        rtn = buf.toString() ;
072                }
073                return rtn ;
074        }
075
076        /**
077         * Unicode 文字列の補正を行います。
078         * encodeがSJIS,Shift_JIS,Windows31J,CP932の場合のみ変換を適用します。
079         *
080         * @param       instr   入力文字列
081         * @param       encode  エンコード
082         * @return      Unicode文字列の補正結果
083         */
084        public static String correctToCP932( final String instr, final String encode ) {
085                if( encode == null ) { return instr; }
086
087                // 8.5.4.2 (2024/01/12) PMD 7.0.0 ForLoopCanBeForeach
088//              for( int i=0; i<ENC_LIST.length; i++ ) {
089//                      if( enc.equalsIgnoreCase( ENC_LIST[i] ) ) { return correctToCP932(str); }
090//              }
091                // 8.5.5.1 (2024/02/29) PMD 7.0.0 OnlyOneReturn メソッドには終了ポイントが 1 つだけ必要
092                String rtn = instr;
093                for( final String enc : ENC_LIST ) {
094                        if( encode.equalsIgnoreCase( enc ) ) {
095//                              return correctToCP932(instr);
096                                rtn = correctToCP932(instr);
097                                break;
098                        }
099                }
100//              return instr;
101                return rtn;
102        }
103
104        /**
105         * キャラクタ単位に、Unicode 文字の補正を行います。
106         *
107         * 風間殿のページを参考にしています。
108         * @see <a href="http://www.ingrid.org/java/i18n/encoding/ja-conv.html" target="_blank" >
109         * http://www.ingrid.org/java/i18n/encoding/ja-conv.html</a>
110         *
111         * @og.rev 8.5.5.1 (2024/02/29) switch式の使用
112         *
113         * @param       ch      入力文字
114         * @return      Unicode文字の補正結果
115         */
116        public static char correctToCP932( final char ch ) {
117                // 8.5.5.1 (2024/02/29) switch式の使用
118//              char rtn = ch;
119//
120//              switch (ch) {
121//      //              case 0x00a2:    return 0xffe0;                                  // ≪
122//      //              case 0x00a3:    return 0xffe1;                                  //  ̄
123//      //              case 0x00ac:    return 0xffe2;                                  // μ
124//      //              case 0x03bc:    return 0x00b5;                                  // ・
125//      //              case 0x2014:    return 0x2015;                                  // ,
126//      //              case 0x2016:    return 0x2225;                                  // ≫
127//      //              case 0x2212:    return 0xff0d;                                  // ―
128//      //              case 0x226a:    return 0x00ab;                                  // ∥
129//      //              case 0x226b:    return 0x00bb;                                  // ヴ
130//      //              case 0x301c:    return 0xff5e;                                  // -
131//      //              case 0x30f4:    return 0x3094;                                  // ~
132//      //              case 0x30fb:    return 0x00b7;                                  // ¢
133//      //              case 0xff0c:    return 0x00b8;                                  // £
134//      //              case 0xffe3:    return 0x00af;                                  // ¬
135//
136//                      case 0x00a2:    rtn = 0xffe0; break;                    // ¢ (1-81, CENT SIGN)
137//                      case 0x00a3:    rtn = 0xffe1; break;                    // £ (1-82, POUND SIGN)
138//                      case 0x00a5:    rtn = 0x005c; break;                    // \ (D/12, YEN SIGN)
139//                      case 0x00ac:    rtn = 0xffe2; break;                    // ¬ (2-44, NOT SIGN)
140//                      case 0x2016:    rtn = 0x2225; break;                    // ∥ (1-34, DOUBLE VERTICAL LINE)
141//                      case 0x203e:    rtn = 0x007e; break;                    // ~ (F/14, OVERLINE)
142//                      case 0x2212:    rtn = 0xff0d; break;                    // - (1-61, MINUS SIGN)
143//                      case 0x301c:    rtn = 0xff5e; break;                    // ~ (1-33, WAVE DASH)
144//
145//      //              case 0x301c:    return 0xff5e;
146//      //              case 0x2016:    return 0x2225;
147//      //              case 0x2212:    return 0xff0d;
148//                      default:                break;                                                  // 4.0.0 (2005/01/31)
149//              }
150//              return rtn;
151
152                // 今でも有効なのかどうか判りません。
153                return switch(ch) {
154        //              case 0x00a2 -> 0xffe0;                  // ≪
155        //              case 0x00a3 -> 0xffe1;                  //  ̄
156        //              case 0x00ac -> 0xffe2;                  // μ
157        //              case 0x03bc -> 0x00b5;                  // ・
158        //              case 0x2014 -> 0x2015;                  // ,
159        //              case 0x2016 -> 0x2225;                  // ≫
160        //              case 0x2212 -> 0xff0d;                  // ―
161        //              case 0x226a -> 0x00ab;                  // ∥
162        //              case 0x226b -> 0x00bb;                  // ヴ
163        //              case 0x301c -> 0xff5e;                  // -
164        //              case 0x30f4 -> 0x3094;                  // ~
165        //              case 0x30fb -> 0x00b7;                  // ¢
166        //              case 0xff0c -> 0x00b8;                  // £
167        //              case 0xffe3 -> 0x00af;                  // ¬
168
169                        case 0x00a2 -> 0xffe0;                  // ¢ (1-81, CENT SIGN)
170                        case 0x00a3 -> 0xffe1;                  // £ (1-82, POUND SIGN)
171                        case 0x00a5 -> 0x005c;                  // \ (D/12, YEN SIGN)
172                        case 0x00ac -> 0xffe2;                  // ¬ (2-44, NOT SIGN)
173                        case 0x2016 -> 0x2225;                  // ∥ (1-34, DOUBLE VERTICAL LINE)
174                        case 0x203e -> 0x007e;                  // ~ (F/14, OVERLINE)
175                        case 0x2212 -> 0xff0d;                  // - (1-61, MINUS SIGN)
176                        case 0x301c -> 0xff5e;                  // ~ (1-33, WAVE DASH)
177
178        //              case 0x301c -> 0xff5e;
179        //              case 0x2016 -> 0x2225;
180        //              case 0x2212 -> 0xff0d;
181                        default     -> ch;                              // 4.0.0 (2005/01/31)
182                };
183        }
184}