source: josm/trunk/src/org/openstreetmap/josm/io/UTFInputStreamReader.java @ 5241

Revision 3372, 2.3 KB checked in by bastiK, 23 months ago (diff)

fixed #5226 - XML encodings and byte-order marker (BOM) support

  • Property svn:eol-style set to native
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.io;
3
4import java.io.InputStream;
5import java.io.InputStreamReader;
6import java.io.IOException;
7import java.io.PushbackInputStream;
8import java.io.UnsupportedEncodingException;
9
10/**
11 * Detects the different UTF encodings from byte order mark
12 */
13public class UTFInputStreamReader extends InputStreamReader {
14    /**
15     * converts input stream to reader
16     * @param defaultEncoding Used, when no BOM was recognized. Can be null.
17     * @return A reader with the correct encoding. Starts to read after the BOM.
18     */
19    public static UTFInputStreamReader create(InputStream input, String defaultEncoding) throws IOException {
20        byte bom[] = new byte[4];
21        String encoding = defaultEncoding;
22        int unread;
23        PushbackInputStream pushbackStream = new PushbackInputStream(input, 4);
24        int n = pushbackStream.read(bom, 0, 4);
25
26        if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
27            encoding = "UTF-8";
28            unread = n - 3;
29        } else if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
30            encoding = "UTF-32BE";
31            unread = n - 4;
32        } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
33            encoding = "UTF-32LE";
34            unread = n - 4;
35        } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
36            encoding = "UTF-16BE";
37            unread = n - 2;
38        } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
39            encoding = "UTF-16LE";
40            unread = n - 2;
41        } else {
42            unread = n;
43        }
44
45        if (unread > 0) {
46            pushbackStream.unread(bom, (n - unread), unread);
47        } else if (unread < -1) {
48            pushbackStream.unread(bom, 0, 0);
49        }
50
51        if (encoding == null) {
52            return new UTFInputStreamReader(pushbackStream);
53        } else {
54            return new UTFInputStreamReader(pushbackStream, encoding);
55        }
56    }
57
58    private UTFInputStreamReader(InputStream in) {
59        super(in);
60    }
61    private UTFInputStreamReader(InputStream in, String cs) throws UnsupportedEncodingException {
62        super(in, cs);
63    }
64}
Note: See TracBrowser for help on using the repository browser.