Coverage Report - de.glossmaker.common.io.UnicodeInputStream
 
Classes in this File Line Coverage Branch Coverage Complexity
UnicodeInputStream
52%
23/44
22%
8/36
4,5
 
 1  
 package de.glossmaker.common.io;
 2  
 
 3  
 import java.io.*;
 4  
 
 5  
 /**
 6  
  * This inputstream will recognize unicode BOM marks and will skip bytes if
 7  
  * getEncoding() method is called before any of the read(...) methods.
 8  
  * 
 9  
  * @author Aki Nieminen
 10  
  */
 11  
 public class UnicodeInputStream extends InputStream {
 12  
         PushbackInputStream internalIn;
 13  74
         boolean isInited = false;
 14  
         String defaultEnc;
 15  
         String encoding;
 16  
 
 17  
         private static final int BOM_SIZE = 4;
 18  
 
 19  74
         public UnicodeInputStream(InputStream in, String defaultEnc) {
 20  74
                 internalIn = new PushbackInputStream(in, BOM_SIZE);
 21  74
                 this.defaultEnc = defaultEnc;
 22  74
         }
 23  
 
 24  
         public String getDefaultEncoding() {
 25  0
                 return defaultEnc;
 26  
         }
 27  
 
 28  
         public String getEncoding() {
 29  74
                 if (!isInited) {
 30  
                         try {
 31  74
                                 init();
 32  0
                         } catch (IOException ex) {
 33  0
                                 IllegalStateException ise = new IllegalStateException(
 34  
                                                 "Init method failed.");
 35  0
                                 ise.initCause(ise);
 36  0
                                 throw ise;
 37  74
                         }
 38  
                 }
 39  74
                 return encoding;
 40  
         }
 41  
 
 42  
         /**
 43  
          * Read-ahead four bytes and check for BOM marks. Extra bytes are unread
 44  
          * back to the stream, only BOM bytes are skipped.
 45  
          */
 46  
         protected void init() throws IOException {
 47  74
                 if (isInited)
 48  0
                         return;
 49  
 
 50  74
                 byte bom[] = new byte[BOM_SIZE];
 51  
                 int n, unread;
 52  74
                 n = internalIn.read(bom, 0, bom.length);
 53  
 
 54  74
                 if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00)
 55  
                                 && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
 56  0
                         encoding = "UTF-32BE";
 57  0
                         unread = n - 4;
 58  74
                 } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)
 59  
                                 && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
 60  0
                         encoding = "UTF-32LE";
 61  0
                         unread = n - 4;
 62  74
                 } else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB)
 63  
                                 && (bom[2] == (byte) 0xBF)) {
 64  0
                         encoding = "UTF-8";
 65  0
                         unread = n - 3;
 66  74
                 } else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
 67  0
                         encoding = "UTF-16BE";
 68  0
                         unread = n - 2;
 69  74
                 } else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
 70  0
                         encoding = "UTF-16LE";
 71  0
                         unread = n - 2;
 72  
                 } else {
 73  
                         // Unicode BOM mark not found, unread all bytes
 74  74
                         encoding = defaultEnc;
 75  74
                         unread = n;
 76  
                 }
 77  
 
 78  74
                 if (unread > 0)
 79  74
                         internalIn.unread(bom, (n - unread), unread);
 80  
 
 81  74
                 isInited = true;
 82  74
         }
 83  
 
 84  
         public void close() throws IOException {
 85  0
                 isInited = true;
 86  0
                 internalIn.close();
 87  0
         }
 88  
 
 89  
         public int read() throws IOException {
 90  0
                 isInited = true;
 91  0
                 return internalIn.read();
 92  
         }
 93  
 }