2011-01-03 13:07:44 -05:00
|
|
|
package com.fsck.k9.mail.internet;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.nio.charset.MalformedInputException;
|
|
|
|
|
2011-01-06 11:55:08 -05:00
|
|
|
class Iso2022JpToShiftJisInputStream extends InputStream
|
|
|
|
{
|
|
|
|
private enum Charset
|
|
|
|
{
|
2011-01-03 13:07:44 -05:00
|
|
|
ASCII, JISX0201, JISX0208,
|
|
|
|
}
|
|
|
|
|
|
|
|
private InputStream mIn;
|
|
|
|
private Charset charset = Charset.ASCII;
|
|
|
|
private int out;
|
|
|
|
private boolean hasOut = false;
|
|
|
|
|
|
|
|
public Iso2022JpToShiftJisInputStream(InputStream in)
|
|
|
|
{
|
|
|
|
mIn = in;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int read() throws IOException
|
|
|
|
{
|
|
|
|
if (hasOut)
|
|
|
|
{
|
|
|
|
hasOut = false;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
int in1 = mIn.read();
|
|
|
|
if (in1 == 0x1b)
|
|
|
|
{
|
|
|
|
in1 = mIn.read();
|
|
|
|
if (in1 == '(')
|
|
|
|
{
|
|
|
|
in1 = mIn.read();
|
|
|
|
if (in1 == 'B' || in1 == 'J')
|
|
|
|
charset = Charset.ASCII;
|
|
|
|
else if (in1 == 'I') // Not defined in RFC 1468 but in CP50221.
|
|
|
|
charset = Charset.JISX0201;
|
|
|
|
else
|
|
|
|
throw new MalformedInputException(0);
|
|
|
|
}
|
|
|
|
else if (in1 == '$')
|
|
|
|
{
|
|
|
|
in1 = mIn.read();
|
|
|
|
if (in1 == '@' || in1 == 'B')
|
|
|
|
charset = Charset.JISX0208;
|
|
|
|
else
|
|
|
|
throw new MalformedInputException(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw new MalformedInputException(0);
|
|
|
|
in1 = mIn.read();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (in1 == '\n' || in1 == '\r')
|
|
|
|
charset = Charset.ASCII;
|
|
|
|
|
2011-01-29 12:56:58 -05:00
|
|
|
if (in1 < 0x21 || in1 >= 0x7f)
|
2011-01-03 13:07:44 -05:00
|
|
|
return in1;
|
|
|
|
|
|
|
|
switch (charset)
|
|
|
|
{
|
2011-01-06 11:55:08 -05:00
|
|
|
case ASCII:
|
|
|
|
return in1;
|
|
|
|
case JISX0201:
|
|
|
|
return in1 + 0x80;
|
|
|
|
case JISX0208:
|
|
|
|
int in2 = mIn.read();
|
2011-01-29 12:56:58 -05:00
|
|
|
if (in2 < 0x21 || in2 >= 0x7f)
|
2011-01-06 11:55:08 -05:00
|
|
|
throw new MalformedInputException(0);
|
2011-01-03 13:07:44 -05:00
|
|
|
|
2011-01-06 11:55:08 -05:00
|
|
|
int out1 = (in1 + 1) / 2 + (in1 < 0x5f ? 0x70 : 0xb0);
|
|
|
|
int out2 = in2 + (in1 % 2 == 0 ? 0x7e : in2 < 0x60 ? 0x1f : 0x20);
|
2011-01-03 13:07:44 -05:00
|
|
|
|
2011-01-06 11:55:08 -05:00
|
|
|
out = out2;
|
|
|
|
hasOut = true;
|
2011-01-03 13:07:44 -05:00
|
|
|
|
2011-01-06 11:55:08 -05:00
|
|
|
return out1;
|
|
|
|
default:
|
|
|
|
throw new RuntimeException();
|
2011-01-03 13:07:44 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|