/**
 * 
 */
package it.laitspa.cpf.faces.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
 * @author andrea
 * 
 */
public class BOMUtils
{

  public static byte[] removeBOM(byte[] data)
      throws Exception
  {
    ByteArrayInputStream bis = new ByteArrayInputStream(data);
    byte[] c_data = removeBOM(bis);
    bis.close();
    return c_data;
  }
  public static byte[] removeBOM(InputStream is)
    throws Exception
  {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    int c = 0;
    byte[] buffer = new byte[512];
    boolean firstRead = false;
    while((c = is.read(buffer)) != -1)
    {
      int offset = 0;
      if(!firstRead)
      {
        firstRead = true;
        // Check BOM.
        //
        if(c >= 2)
        {
          // UTF-16 BIG-ENDIAN
          //
          if(buffer[0] == (byte)0xFE && buffer[1] == (byte)0xFF)
          {
            offset = 2;
          }
          // UTF-16 LITTLE-ENDIAN
          //
          else if(buffer[0] == (byte)0xFF && buffer[1] == (byte)0xFE)
          {
            offset = 2;
          }

          // UTF-8
          //
          if(c > 2 && buffer[0] == (byte)0xEF && buffer[1] == (byte)0xBB && buffer[2] == (byte)0xBF)
          {
            offset = 3;
          }

          // UTF-32 BIG-ENDIAN
          //
          if(c > 3
              && buffer[0] == (byte)0x00 && buffer[1] == (byte)0x00 && buffer[2] == (byte)0xFE
              && buffer[3] == (byte)0xFF)
          {
            offset = 4;
          }

          // UTF-32 LITTLE-ENDIAN
          //
          if(c > 3
              && buffer[0] == (byte)0x00 && buffer[1] == (byte)0x00 && buffer[2] == (byte)0xFE
              && buffer[3] == (byte)0xFF)
          {
            offset = 4;
          }
        }
      }
      bos.write(buffer, offset, (c - offset));
    }

    bos.flush();
    bos.close();

    return bos.toByteArray();
  }
}
