[8378] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
[3372] | 2 | package org.openstreetmap.josm.io;
|
---|
| 3 |
|
---|
[5854] | 4 | import java.io.IOException;
|
---|
[3372] | 5 | import java.io.InputStream;
|
---|
| 6 | import java.io.InputStreamReader;
|
---|
| 7 | import java.io.PushbackInputStream;
|
---|
| 8 | import java.io.UnsupportedEncodingException;
|
---|
| 9 |
|
---|
| 10 | /**
|
---|
| 11 | * Detects the different UTF encodings from byte order mark
|
---|
| 12 | */
|
---|
[6362] | 13 | public final class UTFInputStreamReader extends InputStreamReader {
|
---|
[7509] | 14 |
|
---|
[3372] | 15 | /**
|
---|
[6650] | 16 | * Creates a new {@link InputStreamReader} from the {@link InputStream} with UTF-8 as default encoding.
|
---|
[9231] | 17 | * @param input input stream
|
---|
[6650] | 18 | * @return A reader with the correct encoding. Starts to read after the BOM.
|
---|
[8926] | 19 | * @throws IOException if any I/O error occurs
|
---|
[6650] | 20 | * @see #create(java.io.InputStream, String)
|
---|
| 21 | */
|
---|
| 22 | public static UTFInputStreamReader create(InputStream input) throws IOException {
|
---|
| 23 | return create(input, "UTF-8");
|
---|
| 24 | }
|
---|
| 25 |
|
---|
| 26 | /**
|
---|
| 27 | * Creates a new {@link InputStreamReader} from the {@link InputStream}.
|
---|
[9231] | 28 | * @param input input stream
|
---|
[3372] | 29 | * @param defaultEncoding Used, when no BOM was recognized. Can be null.
|
---|
| 30 | * @return A reader with the correct encoding. Starts to read after the BOM.
|
---|
[8926] | 31 | * @throws IOException if any I/O error occurs
|
---|
[3372] | 32 | */
|
---|
| 33 | public static UTFInputStreamReader create(InputStream input, String defaultEncoding) throws IOException {
|
---|
[6085] | 34 | byte[] bom = new byte[4];
|
---|
[3372] | 35 | String encoding = defaultEncoding;
|
---|
| 36 | int unread;
|
---|
| 37 | PushbackInputStream pushbackStream = new PushbackInputStream(input, 4);
|
---|
| 38 | int n = pushbackStream.read(bom, 0, 4);
|
---|
| 39 |
|
---|
| 40 | if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
|
---|
| 41 | encoding = "UTF-8";
|
---|
| 42 | unread = n - 3;
|
---|
| 43 | } else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
|
---|
| 44 | encoding = "UTF-32BE";
|
---|
| 45 | unread = n - 4;
|
---|
| 46 | } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
|
---|
| 47 | encoding = "UTF-32LE";
|
---|
| 48 | unread = n - 4;
|
---|
| 49 | } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
|
---|
| 50 | encoding = "UTF-16BE";
|
---|
| 51 | unread = n - 2;
|
---|
| 52 | } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
|
---|
| 53 | encoding = "UTF-16LE";
|
---|
| 54 | unread = n - 2;
|
---|
| 55 | } else {
|
---|
| 56 | unread = n;
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | if (unread > 0) {
|
---|
[8345] | 60 | pushbackStream.unread(bom, n - unread, unread);
|
---|
[3372] | 61 | } else if (unread < -1) {
|
---|
| 62 | pushbackStream.unread(bom, 0, 0);
|
---|
| 63 | }
|
---|
| 64 |
|
---|
| 65 | if (encoding == null) {
|
---|
| 66 | return new UTFInputStreamReader(pushbackStream);
|
---|
| 67 | } else {
|
---|
| 68 | return new UTFInputStreamReader(pushbackStream, encoding);
|
---|
| 69 | }
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | private UTFInputStreamReader(InputStream in) {
|
---|
| 73 | super(in);
|
---|
| 74 | }
|
---|
[8510] | 75 |
|
---|
[3372] | 76 | private UTFInputStreamReader(InputStream in, String cs) throws UnsupportedEncodingException {
|
---|
| 77 | super(in, cs);
|
---|
| 78 | }
|
---|
| 79 | }
|
---|