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.mail; 017 018// import java.io.InputStream; 019// import java.io.OutputStream; 020import java.io.ByteArrayOutputStream; 021// import java.io.ByteArrayInputStream; 022import 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&all=644&s=681 039 * にて YOSI さんが公開されたコードも参考にしています(というか実質同じです)。 040 * 041 * @version 4.0 042 * @author Kazuhiko Hasegawa 043 * @since JDK5.0, 044 */ 045class 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 * 1文字の2バイト 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}