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     * æ–?­—関係ã?コンãƒã?ã‚¿ã§ã™ã?
037     * ä¸?ƒ¨ã‚³ãƒ¼ãƒ‰ã?オリジナル㯠<a href="http://www-cms.phys.s.u-tokyo.ac.jp/~naoki/CIPINTRO/CCGI/kanjicod.html">Japanese Kanji Code</a>ã«ã¦å…¬é–‹ã•れã¦ã?‚‹ã‚‚ã?ã§ã™ã?
038     * ã¾ãŸã?http://www.sk-jp.com/cgi-bin/treebbs.cgi?kako=1&amp;all=644&amp;s=681
039     * ã«ã¦ YOSI ã•ã‚“ãŒå?é–‹ã•れãŸã‚³ãƒ¼ãƒ‰ã‚‚å‚è?ã«ã—ã¦ã?¾ã?ã¨ã?†ã‹å®Ÿè³ªåŒã˜ã§ã?ã€?
040     *
041     * @version  4.0
042     * @author   Kazuhiko Hasegawa
043     * @since    JDK5.0,
044     */
045    class CharCodeConverter {
046            private static final byte[] SJIS_KANA;  // 5.1.9.0 (2010/09/01) public â‡?private ã¸å¤‰æ›´
047    
048            /**
049             * インスタンスã®ç”Ÿæ?を抑止ã—ã¾ã™ã?
050             */
051            private CharCodeConverter() {
052                    // 何もã‚りã¾ã›ã‚“ã€?PMD エラー回é¿)
053            }
054    
055            static {
056                    try {
057                            // 全角ã¸ã®å¤‰æ›ãƒ??ブル
058                            SJIS_KANA = "。ã?ã€ã?・ヲァィゥェォャュョãƒ??アイウエオカキクケコサシスセソタãƒãƒ„ãƒ?ƒˆãƒŠãƒ‹ãƒŒãƒãƒŽãƒãƒ’フヘã?マミãƒ?ƒ¡ãƒ¢ãƒ¤ãƒ¦ãƒ¨ãƒ©ãƒªãƒ«ãƒ¬ãƒ­ãƒ¯ãƒ³ã‚›ã?".getBytes("Shift_JIS");
059                    } catch( UnsupportedEncodingException ex ) {
060                            throw new RuntimeException( "CANT HAPPEN",ex );
061                    }
062            }
063    
064            /**
065             * Shift_JIS エンコーãƒ?‚£ãƒ³ã‚°ã‚¹ã‚­ãƒ¼ãƒ?«åŸºã¥ããƒã‚¤ãƒˆå?ã‚?
066             * ISO-2022-JP エンコーãƒ?‚£ãƒ³ã‚°ã‚¹ã‚­ãƒ¼ãƒ?«å¤‰æ›ã—ã¾ã™ã?
067             * 「åŠè§’カナã?ã¯å¯¾å¿œã™ã‚‹å?角文字ã«å¤‰æ›ã—ã¾ã™ã?
068             *
069             * @param sjisBytes byte[] エンコードã™ã‚‹Shift_JISãƒã‚¤ãƒˆé?åˆ?
070             *
071             * @return byte[] 変æ›å¾Œã?ISO-2022-JP(JIS)ãƒã‚¤ãƒˆé?åˆ?not null)
072             */
073            public static byte[] sjisToJis( final byte[] sjisBytes ) {
074                    ByteArrayOutputStream out = new ByteArrayOutputStream();
075                    boolean nonAscii = false;
076                    int len = sjisBytes.length;
077                    for(int i = 0; i < len; i++ ) {
078                            if(sjisBytes[i] >= 0) {
079                                    if(nonAscii) {
080                                            nonAscii = false;
081                                            out.write(0x1b);
082                                            out.write('(');
083                                            out.write('B');
084                                    }
085                                    out.write(sjisBytes[i]);
086                            } else {
087                                    if(!nonAscii) {
088                                            nonAscii = true;
089                                            out.write(0x1b);
090                                            out.write('$');
091                                            out.write('B');
092                                    }
093                                    int bt = sjisBytes[i] & 0xff;
094                                    if(bt >= 0xa1 && bt <= 0xdf) {
095                                            // åŠè§’カナã?全角ã«å¤‰æ›
096                                            int kanaIndex = (bt - 0xA1) * 2;
097                                            sjisToJis(out, SJIS_KANA[kanaIndex], SJIS_KANA[kanaIndex + 1]);
098                                    } else {
099                                            i++;
100                                            if(i == len) { break; }
101                                            sjisToJis(out, sjisBytes[i - 1], sjisBytes[i]);
102                                    }
103                            }
104                    }
105                    if(nonAscii) {
106                            out.write(0x1b);
107                            out.write('(');
108                            out.write('B');
109                    }
110                    return out.toByteArray();
111            }
112    
113            /**
114             * ?‘文字ã??’ãƒã‚¤ãƒ?Shift_JIS コードを JIS コードã«å¤‰æ›ã—ã¦æ›¸ãå?ã—ã¾ã™ã?
115             */
116            private static void sjisToJis(
117                                    final ByteArrayOutputStream out, final byte bhi, final byte blo) {
118                    int hi = (bhi << 1) & 0xFF;
119                    int lo = blo & 0xFF;
120                    if(lo < 0x9F) {
121                            if(hi < 0x3F) { hi += 0x1F; } else { hi -= 0x61; }
122                            if(lo > 0x7E) { lo -= 0x20; } else { lo -= 0x1F; }
123                    } else {
124                            if(hi < 0x3F) { hi += 0x20; } else { hi -= 0x60; }
125                            lo -= 0x7E;
126                    }
127                    out.write(hi);
128                    out.write(lo);
129            }
130    }