Skip to content

Instantly share code, notes, and snippets.

@gaeeyo
Last active December 29, 2015 04:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gaeeyo/7614651 to your computer and use it in GitHub Desktop.
Save gaeeyo/7614651 to your computer and use it in GitHub Desktop.
Android 4.4でSJISのエンコードで文字化けして困る件の対策。雑ですみません。 Android 4.4まではEUC-JPのエンコードとデコードでNEC拡張漢字などが化けていましたが、4.4では化けなくなっていました。 【注】Android 4.4未満ではデフォルトのencoderを使ったほうがいいです。パフォーマンスが悪いですしAndroid 4.4未満では①や㈱をEUCにエンコードするときに文字化けしてしまう(Android 4.4では文字化けしない)ためです。
package jp.syoboi.utils.charset;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
/**
* Android 4.4 で SJIS のエンコードがバグっていて文字化けする問題の対策用
* エンコード時は EUC-JP => JIS => SJIS の変換を行う
*/
public class Charset_SJIS extends Charset {
Charset mSJIS;
Charset mEUC;
public Charset_SJIS() {
super("SJIS", new String[] { "SJIS" });
mSJIS = Charset.forName("SJIS");
mEUC = Charset.forName("EUC-JP");
}
@Override
public boolean contains(Charset charset) {
return false;
}
@Override
public CharsetDecoder newDecoder() {
return mSJIS.newDecoder();
}
@Override
public CharsetEncoder newEncoder() {
return new Encoder(mEUC.newEncoder());
}
public static class Encoder extends CharsetEncoder {
CharsetEncoder mEucEncoder;
ByteBuffer mTmp;
int mTmpPos;
protected Encoder(CharsetEncoder base) {
super(base.charset(), base.averageBytesPerChar(), base.maxBytesPerChar());
mEucEncoder = base;
mEucEncoder.onUnmappableCharacter(CodingErrorAction.REPLACE);
mEucEncoder.onMalformedInput(CodingErrorAction.REPLACE);
mTmp = ByteBuffer.allocate(1024);
}
@Override
protected CoderResult encodeLoop(CharBuffer in, ByteBuffer out) {
CoderResult result = null;
if (mTmp.position() > 0) {
mTmp.flip();
mTmp.rewind();
result = eucToJis(mTmp, out);
mTmp.compact();
if (result != CoderResult.OVERFLOW) {
return result;
}
}
result = mEucEncoder.encode(in, mTmp, false);
int pos = mTmp.position();
mTmp.flip();
mTmp.rewind();
result = eucToJis(mTmp, out);
mTmp.position(pos);
mTmp.compact();
return result;
}
CoderResult eucToJis(ByteBuffer in, ByteBuffer out) {
while (in.hasRemaining()) {
if (out.remaining() < 2) {
return CoderResult.OVERFLOW;
}
byte b = in.get();
if ((byte) 0x00 <= b && b <= (byte) 0x7f) {
; // 何もしない
out.put(b);
} else if (b == (byte) 0x8e && in.hasRemaining()) {
// 半角カナ
out.put(in.get());
} else if ((byte) 0xA1 <= b && b <= (byte) 0xFE
&& in.hasRemaining()) {
int c1 = (b & 0x7f);
int c2 = (in.get() & 0x7f);
if ((c1 & 1) == 1) {
c1 = ((c1 + 1) / 2) + 0x70;
c2 = c2 + 0x1f;
} else {
c1 = (c1 / 2) + 0x70;
c2 = c2 + 0x7d;
}
if (c1 >= 0xa0) {
c1 = c1 + 0x40;
}
if (c2 >= 0x7f) {
c2 = c2 + 1;
}
out.put((byte) (c1 & 0xff));
out.put((byte) (c2 & 0xff));
} else {
out.put(b);
}
}
return CoderResult.UNDERFLOW;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment