Package fi.celia.convert.chars

Source Code of fi.celia.convert.chars.DecoderCharacterSet

package fi.celia.convert.chars;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
//import java.nio.charset.CoderResult;
import java.util.logging.Logger;
import java.util.List;
import java.util.ArrayList;

/**
* Tämä value-luokka on tarkoitettu 1. muuntamaan merkkijonoja merkistästä
* toiseen. Tuetut merkistät ovat ainakin tässä luokassa luetellut
* merkistät (ks. enum CHARACTERSET). 2. Lisäksi luokalle voi muuttaa
* myäs sekamerkistäjä merkistäistä annettuun merkistään (metthodi
* xxx.)
* <p>
* Se luo ja säilyttää Charset from- ja
* To-oliot sekä niittä vastaavat enum literaalit.
* Luokan objekteja käytetään kutsuttaessa char ja
* Character muunnos-metodeita sekä merkkijonon characterset
* muunnosfunktioissa. Samaa luokan objektia käytetään kutsuttaessa
* convertCharacterSetBytes -methodia, jolloin luotu CharacterSetDecoder
* objekti nopeuttaa kutsua, kun ei tarvitse luoda samoja character objekteja
* joka kerta convert... methodia kutsuttaessa. Dokumentaatio ks
* CharacterSet.convertCharacterSetBytes(...).
* <p>
* Tarvittaessa merkkijonon muunnosfunktiota
* voidaan kutsua myäs ilman tämän luokan objectia, pelkillä
* enum-arvoilla (from ja to-arvoilla, siis mistä charactersetistä
* muunnetaan ja mihin charactersettiin).
* <p>
* Huom! v. 1.1.1 Korjattu decoder-olion bugi eli jos syättädatan merkisto
* on sama kuin muunnettavan merkistän, nyt ei tehdä muunnosta ollenkaan,
* vaan data palautetaan muuttumattomana (, paitsi silloin kun halutaan,
* että CR-merkki lisättävän aik. stringin perään).
* Jos näin ei tehtäisi bugi aiheuttaisi, tiedoston tai streamin loppuun
* ^@-merkkejä xx kpl:tta.
* <p>
* Alla esimerkki käytästä koodissa:
* <p>
*
* <code>
*     // .......
  public static final String UTF_8 = "UTF-8";
  public static final String UTF_16 = "UTF-16";
  public static final String UTF_16BE = "UTF-16BE";
  public static final String UTF_16LE = "UTF-16LE";
  public static final String ISO_8859_1 = "ISO-8859-1";
  public static final String US_ASCII = "US-ASCII";
 
  private static String defLanguageRead = UTF_8.toString().replace('_', '-');
  private static String defLanguageWrite = ISO_8859_1.toString().replace('_', '-');
    // ....

*   private static void muunnaDtbookTextFromUtf8ToLatin1(String dest)
  throws Exception
  {
    File destFile = new File(dest);
    if (!destFile.exists() )
    {
      String msg = "Muunnettavaa tiedostoa " + dest +"ei ole!";
      logger.severe(msg);
      Virhe(msg);
    }
    
    String readWithCharSet = defLanguageRead;
    String writeWithCharSet = defLanguageWrite;
      System.out.println("luku-merkistä=" + readWithCharSet);
      System.out.println("kirjoitus-merkistä=" + writeWithCharSet);
       
      DecoderCharacterSet.CHARACTERSET writeCharacterSet =
              getCharacterSet(writeWithCharSet);
      DecoderCharacterSet.CHARACTERSET readCharacterSet =
          getCharacterSet(readWithCharSet);

      DecoderCharacterSet decoder = new DecoderCharacterSet(
                  readCharacterSet,  writeCharacterSet);
    String strTeos = decoder.readFromFileByUsingReadCharacterSet(dest);
    if (strTeos == null)
    {
      String msg = "Tiedostosta " + dest +"ei saatu luettua merkkejä!";
      logger.severe(msg);
      Virhe(msg);
    }
   
    String tmpFileName = dest +".tmp";
    File tmpFile = new File(tmpFileName);
    FileOutputStream bos = new FileOutputStream(tmpFile);
    // Alkuun ensin merkistä:
    bos.write(decoder.convertCharacterSetBytes(annaMerkisto(), CR));
    // Sitten varsinainen julk. teostiedosto.
    bos.write(decoder.convertCharacterSetBytes(strTeos, ""));
    bos.close();
    ........
  }
* </code>
*
* @author tuomask
*
*/
public class DecoderCharacterSet
{
  // newString = myString.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
 
  /**
   * Merkkijonojen nimiä kun konvertoidaan:
   */
  public static final String UTF_8 = "UTF-8";
  public static final String UTF_16 = "UTF-16";
  public static final String UTF_16BE = "UTF-16BE";
  public static final String UTF_16LE = "UTF-16LE";
  public static final String ISO_8859_1 = "ISO-8859-1";
  public static final String US_ASCII = "US-ASCII";
 
  private static boolean bDebug = false;
 
  public enum CHARACTERSET { UTF_8, UTF_16, UTF_16BE, UTF_16LE,
                ISO_8859_1, US_ASCII
                }

  private static String defLanguage = UTF_8.toString().replace('_', '-');

  private Charset fromcharset = null;
  private Charset tocharset = null;
  private String strFromCharacterSet;
  private String strToCharacterSet;
  private CharsetDecoder fromDecoder;
  private CharsetEncoder fromEncoder;
  private CharsetDecoder toDecoder;
  private CharsetEncoder toEncoder;
 
  private static int maxArray = CHARACTERSET.values().length;
  private DecoderCharacterSet [] arrayCharSetDecoders
              = new DecoderCharacterSet[maxArray];

  private static Charset [] arrayCharsetEncoders;

  private static Logger logger;
 
  public static void
  setLogger(Logger p_logger)
  {
    logger = p_logger;
  }   

 
  /*
   *
   */
  /*
  public class From88591IntoUTF8CharCode
  {
    private final int i88591;
    private final char ch88591;
    private final String strUTF8;
    private  char chUTF8;
    private  int iUTF8;
    private char chUTF8_1 = (char)-1;
    private char chUTF8_2 = (char)-1;
    private char chUTF8_3 = (char)-1;
    private char chUTF8_4 = (char)-1;
   
    public From88591IntoUTF8CharCode(char p_ch88591)
    throws UnsupportedEncodingException

    {
      ch88591 = p_ch88591;
     
      i88591 = ch88591;
      strUTF8 = new String(new Character(ch88591).toString().getBytes(UTF_8));
      if (strUTF8 != null)
      {
        int max = strUTF8.length();
        if (max > 0)
        {
          for(int i = 0; i < max; i++)
          {
            if (i == 0)
              chUTF8_1 = strUTF8.charAt(i);
            else
            if (i == 1)
              chUTF8_2 = strUTF8.charAt(i);
            else
            if (i == 2)
              chUTF8_3 = strUTF8.charAt(i);
            else
            if (i == 3)
              chUTF8_4 = strUTF8.charAt(i);
          }
        }
      }
    }
  }
  */
   
  static {
    // aseta valmiiksi checkAndConvertIntoWriteCharacterSet-methodia
    // varten arrayCharsetEncoders-taulukko sekä vastaava satsi
    // arrayCharSetDecoders-taulukko:
    arrayCharsetEncoders = new Charset[maxArray];
    arrayCharsetEncoders[0] = Charset.forName(UTF_8.toString().replace('_', '-'));
    arrayCharsetEncoders[1] = Charset.forName(UTF_16.toString().replace('_', '-'));
    arrayCharsetEncoders[2] = Charset.forName(UTF_16BE.toString().replace('_', '-'));
    arrayCharsetEncoders[3] = Charset.forName(UTF_16LE.toString().replace('_', '-'));
    arrayCharsetEncoders[4] = Charset.forName(ISO_8859_1.toString().replace('_', '-'));
    arrayCharsetEncoders[5] = Charset.forName(US_ASCII.toString().replace('_', '-'));
  }


  public DecoderCharacterSet(CHARACTERSET p_fromCharacterSet,
             CHARACTERSET p_toCharacterSet)
  {
    strFromCharacterSet = p_fromCharacterSet.toString().replace('_', '-');
    strToCharacterSet = p_toCharacterSet.toString().replace('_', '-');
       fromcharset = Charset.forName(strFromCharacterSet)
       tocharset = Charset.forName(strToCharacterSet);
       fromDecoder = fromcharset.newDecoder();
       fromEncoder = fromcharset.newEncoder();        
       toDecoder = tocharset.newDecoder();
       toEncoder = tocharset.newEncoder();                    
  }
 
  Charset getFromCharset()   
  {
    return fromcharset;
  }
 
  Charset getToCharset()
  {
    return tocharset;
  }

 
  public String getFromCharacterSetString()
  {
    return strFromCharacterSet;
  }

  public String getToCharacterSetString()
  {
    return strToCharacterSet;
  }

  public CharsetDecoder getFromDecoder() { return fromDecoder; }
  public CharsetEncoder getFromEncoder() { return fromEncoder; }
  public CharsetDecoder getToDecoder() { return toDecoder; }
  public CharsetEncoder gettoEncoder() { return toEncoder; }
 
 
  /**
   * Katso kutsuttava funktion Javadoc-dokumentointi.
   * @param value
   * @param CR
   * @return Ks yllä.
   * @throws CharacterCodingException
   * @throws UnsupportedEncodingException
   * @throws NullPointerException
   */
  public byte []
  convertCharacterSetBytes( String value,
                        String CR)
                    throws   CharacterCodingException,
                        UnsupportedEncodingException,
                        NullPointerException
  {
    return convertCharacterSetBytes(this, value, CR);
  }


  /**
   * Katso kutsuttavan funktion Javadoc-dokumentointi.
   * @param value
   * @param CR
   * @return Ks yllä.
   * @throws CharacterCodingException
   * @throws UnsupportedEncodingException
   * @throws NullPointerException
   */
  public byte []
     convertCharacterSetBytes( Character value,
                           String CR)
     throws   CharacterCodingException,
         UnsupportedEncodingException,
         NullPointerException
     {
       return convertCharacterSetBytes(this, value, CR);
     }

  /**
   * Katso kutsuttavan funktion Javadoc-dokumentointi.
   * @param value
   * @param CR
   * @return Ks yllä.
   * @throws CharacterCodingException
   * @throws UnsupportedEncodingException
   * @throws NullPointerException
   */
  public byte []
     convertCharacterSetBytes( char value,
                              String CR)
     throws   CharacterCodingException,
         UnsupportedEncodingException,
         NullPointerException
     {
       return convertCharacterSetBytes(this,
           Character.valueOf(value), CR);
     }

  /**
   * Katso kutsuttavan funktion Javadoc-dokumentointi.
   * @param value
   * @return Ks yllä.
   * @throws CharacterCodingException
   * @throws NullPointerException
   */
  public boolean
  isCharacterSetBytes(char value)
  throws   //MalformedInputException,
      CharacterCodingException,
      NullPointerException
  {
    return isCharacterSetBytes(this.tocharset /* fromcharset */,
        Character.valueOf(value).toString());
  }

  /**
   * Katso kutsuttavan funktion Javadoc-dokumentointi.
   * @param value
   * @return Ks yllä.
   * @throws CharacterCodingException
   * @throws NullPointerException
   */
  public boolean
  isCharacterSetBytes(Character value)
  throws   //MalformedInputException,
      CharacterCodingException,
      NullPointerException
  {
    return isCharacterSetBytes(fromcharset, value);
  }

  /**
   * Katso kutsuttavan funktion Javadoc-dokumentointi.
   * @param value
   * @return Ks yllä.
   * @throws CharacterCodingException
   * @throws NullPointerException
   */
  public boolean
  isCharacterSetBytes(String value)
  throws   //MalformedInputException,
      CharacterCodingException,
      NullPointerException
  {
    return isCharacterSetBytes(fromcharset, value);
  }
 
  /**
   * Tämä methodi palauttaa tietyn characterset merkin bytet toisen charactersetin
   * byteissä. Eli muuntaa byte tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param csdecoder Decoder olio, joka kertoo mistä character setistä muunnetaan
   *                  ja mihin settiin
   * @param value Muunnetava merkki char:na
   * @param CR line feed arvo stringinä, jos halutaan lisättävä tulosbyte-taulukon
   *        perään. Jos parametrin arvo on null tai "", niin sitä ei lisätä.
   * @return Ks yllä.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws UnsupportedEncodingException Kuten nimi sanoo
   */
  public static byte []
  getCharacterSetBytes(DecoderCharacterSet csdecoder,
               char value,
               String CR)
  throws   CharacterCodingException,
      UnsupportedEncodingException,
      NullPointerException
  {
   
    return convertCharacterSetBytes(csdecoder,
           Character.valueOf(value), CR);
  }

  /**
   * Tämä methodi palauttaa tietyn characterset merkin bytet toisen charactersetin
   * byteissä MIKäLI KYSEINEN DATA ON LUETTU SAMALLA TAVALLA KUIN readCharacterset'ssä
   * vaitetään (ks readFromFileByUsingReadCharacterSet(...). Eli muuntaa byte tsasolla
   * charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param csdecoder Decoder olio, joka kertoo mistä character setistä muunnetaan
   *                  ja mihin settiin
   * @param value Muunnetava merkki Character:na
   * @param CR line feed arvo stringinä, jos halutaan lisättävä tulosbyte-taulukon
   *        perään. Jos parametrin arvo on null tai "", niin sitä ei lisätä.
   * @return Ks yllä.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws UnsupportedEncodingException Kuten nimi sanoo
   */
  public static byte []
  convertCharacterSetBytes(DecoderCharacterSet csdecoder,
               Character value,
               String CR)
  throws   CharacterCodingException,
      UnsupportedEncodingException,
      NullPointerException
  {
   
    return convertCharacterSetBytes(csdecoder, value.toString(), CR);
  }

  /**
   * Tämä methodi palauttaa tietyn characterset merkin bytet toisen charactersetin
   * byteissä. Eli muuntaa byte tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param fromCharacterSet Mistä charactersetistä muunntetaan
   * @param toCharacterSet Mihin charactersettiin muunntetaan
   * @param value Muunnetava merkki Character:na
   * @param CR line feed arvo stringinä, jos halutaan lisättävä tulosbyte-taulukon
   *        perään. Jos parametrin arvo on null tai "", niin sitä ei lisätä.
   * @return Ks yllä.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws UnsupportedEncodingException Kuten nimi sanoo
   */
  public static byte []
  convertCharacterSetBytes(CHARACTERSET fromCharacterSet,
               CHARACTERSET toCharacterSet,
               String value,
               String CR)
  throws   CharacterCodingException,
      UnsupportedEncodingException,
      NullPointerException
  {
    DecoderCharacterSet csdecoder = new DecoderCharacterSet(fromCharacterSet,
                                    toCharacterSet);
    return convertCharacterSetBytes(csdecoder, value, CR);
  }

  /*
   * Tämä methodi palauttaa tietyn characterset merkkijonon bytet toisen charactersetin
   * byteissä. Eli muuntaa byte tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param fromCharacterSet Mistä charactersetistä muunntetaan
   * @param toCharacterSet Mihin charactersettiin muunntetaan
   * @param value Muunnetava merkkijono, Jos value on null tai "",  niin
   *              palauttaa array byte[0]:n
   * @param CR line feed arvo stringinä, jos halutaan lisättävä tulosbyte-taulukon
   *        perään. Jos parametrin arvo on null tai "", niin sitä ei lisätä.
   * @return Ks yllä.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws UnsupportedEncodingException Kuten nimi sanoo
   */
  /*
  public static byte []
  convertCharacterSetBytes(CHARACTERSETS fromCharacterSet,
               CHARACTERSETS toCharacterSet,
               String value,
               String CR)
  throws   CharacterCodingException,
      UnsupportedEncodingException,
      NullPointerException
  {
    if (value == null || "".equals(value))
      return new byte[0]; 
    if (fromCharacterSet == null)
      throw new NullPointerException("fromCharacterSet paramter is null!");
    if (toCharacterSet == null)
      throw new NullPointerException("toCharacterSet paramter is null!");
                          
    try {
           Charset fromcharset = Charset.forName(fromCharacterSet.toString()); //
           Charset tocharset = Charset.forName(toCharacterSet.toString());
           ByteBuffer inputBuffer = ByteBuffer.wrap(value.getBytes()); //

             CharsetDecoder fromDecoder = fromcharset.newDecoder();

             CharBuffer data;
        try {  // yritään muunnosta sellaisena kuin data tulee
            data = fromDecoder.decode(inputBuffer);
           } catch (java.nio.charset.MalformedInputException mfie) {
             try { // jos ei onnistu, yritetään muuttaa dataa lähtächaractersetiksi
               // byte-tasolla, jonka jälkeen muunnos:
             inputBuffer = ByteBuffer.wrap(value.getBytes(fromCharacterSet.toString())); //
             data = fromDecoder.decode(inputBuffer);
               } catch (java.nio.charset.MalformedInputException mfie2) {
                 throw mfie2;
               }
           }
          
           // muunnos onnistui source charactersettiin, voidaan yrittää muuntaa
           // kohde charactersettiin:
          
           ByteBuffer outputBuffer;
                          
           outputBuffer = tocharset.encode(data);
           byte[] tmp = outputBuffer.array();
           if (CR == null || "".equals(CR))
             return tmp;
                     
           // jos cr annettu, lisätään se tulos arrayn perään, joka palautetaan:
          
           byte[] crBytes = CR.getBytes();
           int maxTmp = tmp.length;
           int max = maxTmp + crBytes.length;
           int tmpInd = 0;
           byte[] outputData = new byte[max];
                      
           for(int i = 0; i < maxTmp; i++)
            outputData[i] = tmp[i];
                        
           for(int i = maxTmp; i < max; i++)
            outputData[i] = crBytes[tmpInd++];
                        
           return outputData ;
     } catch (CharacterCodingException e) {
//         } catch (Exception e) {
           throw e;          
     } catch (UnsupportedEncodingException e2) {
//        } catch (Exception e) {
          throw e2;
         }
   }
  */
 
  /**
   * Tämä methodi palauttaa tietyn characterset merkkijonon bytet toisen charactersetin
   * byteissä MIKäLI KYSEINEN DATA ON LUETTU SAMALLA TAVALLA KUIN readCharacterset'ssä
   * vaitetään (ks readFromFileByUsingReadCharacterSet(...). . Eli muuntaa byte
   * tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param csdecoder Decoder olio, joka kertoo mistä character setistä muunnetaan
   *                  ja mihin settiin
   * @param value Muunnetava merkkijono, Jos value on null tai "",  niin
   *              palauttaa array byte[0]:n
   * @param CR line feed arvo stringinä, jos halutaan lisättävä tulosbyte-taulukon
   *        perään. Jos parametrin arvo on null tai "", niin sitä ei lisätä.
   * @return Ks yllä.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws UnsupportedEncodingException Kuten nimi sanoo
   */
  public static byte []
  convertCharacterSetBytes(DecoderCharacterSet csdecoder,
               String value,
               String CR)
  throws   CharacterCodingException,
      UnsupportedEncodingException,
      NullPointerException
  {
    if (value == null || "".equals(value))
      return new byte[0]

    String fromCharacterSet = csdecoder.getFromCharacterSetString();
    String toCharacterSet = csdecoder.getToCharacterSetString();
    Charset fromcharset = csdecoder.getFromCharset()
       Charset tocharset = csdecoder.getToCharset();             
   
    if (fromCharacterSet == null)
      throw new NullPointerException("fromCharacterSet paramter is null!");
//    if (toCharacterSet == null)
//      throw new NullPointerException("toCharacterSet paramter is null!");
     
    /* Kun merkistät ovat samat eli muunnettavan ja
     * mihin merkistään muunnetaan, niin silloin decoder
     * näyttää tekevän monta ylimääräisiä ^@ -merkkejä streamin
     * loppuun. Ja siksi tutkitaan, jos merkistät samat ei
     * tehdä muunnosta, vaan palautetaan muuttumaton data:
     */
    if (toCharacterSet != null && fromcharset != null
      && toCharacterSet.equals(fromCharacterSet))
    {
      if (CR == null || "".equals(CR))
        return value.getBytes();
     
      return new String(value+CR).getBytes();                        
    }
     
     
    try {
           //ByteBuffer inputBuffer = ByteBuffer.wrap(value.getBytes()); //
           ByteBuffer inputBuffer = ByteBuffer.wrap(value.getBytes(fromCharacterSet)); //
             CharsetDecoder fromDecoder = csdecoder.getFromDecoder();

             CharBuffer data;
        try // yritään muunnosta sellaisena kuin data tulee
            data = fromDecoder.decode(inputBuffer);
           } catch (java.nio.charset.MalformedInputException mfie) {
             try { // jos ei onnistu, yritetään muuttaa dataa lähtächaractersetiksi
               // byte-tasolla, jonka jälkeen muunnos:
             inputBuffer = ByteBuffer.wrap(value.getBytes(fromCharacterSet)); //
             data = fromDecoder.decode(inputBuffer);
               } catch (java.nio.charset.MalformedInputException mfie2) {
                 throw mfie2;
               }
           }
          
           // muunnos onnistui source charactersettiin, voidaan yrittää muuntaa
           // kohde charactersettiin:
          
           ByteBuffer outputBuffer;
                          
           outputBuffer = tocharset.encode(data);
           byte[] tmp = outputBuffer.array();
           //String srtTest = new String(data);
           //String srtTest2 = new String(tmp);
           /*
           //System.out.println("data=" +srtTest);
           System.out.println("tmp=" +srtTest2);
           File f = new File("tmp.tmp");
           try {
             FileOutputStream fos = new FileOutputStream (f);
             fos.write(srtTest2.getBytes());
             fos.flush();
             fos.close();
           } catch (FileNotFoundException e){
            
           } catch (IOException ioe){
            
           }
           */
           if (CR == null || "".equals(CR))
             return tmp;
                     
           // jos cr annettu, lisätään se tulos arrayn perään, joka palautetaan:
          
           byte[] crBytes = CR.getBytes();
           int maxTmp = tmp.length;
           int max = maxTmp + crBytes.length;
           int tmpInd = 0;
           byte[] outputData = new byte[max];
                      
           for(int i = 0; i < maxTmp; i++)
            outputData[i] = tmp[i];
                        
           for(int i = maxTmp; i < max; i++)
            outputData[i] = crBytes[tmpInd++];
                        
           return outputData ;
     } catch (CharacterCodingException e) {
//         } catch (Exception e) {
           throw e;          
     } catch (UnsupportedEncodingException e2) {
//        } catch (Exception e) {
          throw e2;
         }
   }

  /**
   * Tämä methodi palauttaa tietyn characterset merkkijonon bytet toisen charactersetin
   * byteissä. Eli muuntaa byte tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param charset Charset eli mistä character setistä muunnetaan
   * @param value Muunnetava merkkijono, Jos value on null tai "",  niin
   *              palauttaa true:n, muuten false.
   * @return jos value sisältää kyseisen character setin, palauttaa true:n, muuten false.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws NullpointerException Jos param null, paitsi value
   */
  public static boolean
  isCharacterSetBytes(Charset charset,
               String value)
  throws   //MalformedInputException,
      CharacterCodingException,
      NullPointerException
  {
    if (value == null || "".equals(value))
      return true

    if (charset == null)
      throw new NullPointerException("fromcharset paramter is null!");
                          
       ByteBuffer inputBuffer = ByteBuffer.wrap(value.getBytes()); //
         CharsetDecoder decoder = charset.newDecoder();                

         try // yritään muunnosta sellaisena kuin data tulee
           CharBuffer data = decoder.decode(inputBuffer);
            return true ;
       } catch (java.nio.charset.MalformedInputException mfie) {
         if (bDebug)
           mfie.printStackTrace();
         if (logger != null)
           logger.severe(mfie.toString());

         //throw mfie;
       }          
    return false;
   }

  /**
   * Tämä methodi palauttaa tietyn characterset merkkijonon bytet toisen charactersetin
   * byteissä. Eli muuntaa byte tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param fromcharset Charset eli mistä character setistä muunnetaan
   * @param value testattava Character
   * @return jos value sisältää kyseisen character setin, palauttaa true:n, muuten false.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws NullpointerException Jos param null, paitsi value
   */
  public static boolean
  isCharacterSetBytes(Charset fromcharset,
               Character value)
  throws   //MalformedInputException,
      CharacterCodingException,
      NullPointerException
  {
    return isCharacterSetBytes(fromcharset, value.toString());
   }

  /**
   * Tämä methodi palauttaa tietyn characterset merkkijonon bytet toisen charactersetin
   * byteissä. Eli muuntaa byte tsasolla charactersetistä toiseen. Ks CHARACTERSETS'n
   * literaatlit. Olettaa että parametrina annettava value merkkijono on
   * kokonaan samaa merkkijonoa/kutsukerta, mutta jonka arvo voi vaihdella
   * eri kutsukerroilla.
   *
   * @param fromcharset Charset eli mistä character setistä muunnetaan
   * @param value testattava Character
   * @return jos value sisältää kyseisen character setin, palauttaa true:n, muuten false.
   * @throws CharacterCodingException Jos ei tuettu characterset set, tai muunnos ei onnistu
   * @throws NullpointerException Jos param null, paitsi value
   */
  public static boolean
  isCharacterSetBytes(Charset fromcharset,
               char value)
  throws   //MalformedInputException,
      CharacterCodingException,
      NullPointerException
  {
    return isCharacterSetBytes(fromcharset, Character.valueOf(value).toString());
   }

  /***
   * Tämä methodi on tarkoitettu varmistamaan, että kun konvertoidaan (decodaus)
   * dataa eli merkkijonoja Javan merkistästä toiseen, on ensin esim tiedostosta
   * luettava juuri samalla merkkikoodauksella kuin sitten vastaavan dataa
   * konvertoitaessa käytetään. Eli 1) kun ensin luodaan decoder-olio, jolle
   * kerrotaan mitä merkkikoodausta käytetään luettaessa ja mitä merkkikoodausta
   * kirjoitettaessa. 2) Sitten luetaan esim tällä methodilla data eli esim
   * tiedoston sisältä ja 3) lopuksi kutsutaan decoder-olion convertCharacterSetBytes
   * -mehtodia, jossa kyseisen datan muunnos tapahtuu, mikäli data on ensin luettu
   * tällä readFromFileByUsingReadCharacterSet-metodilla!
   * @param readFileName Luettavan tiedoston nimi
   * @return Luettu data tiedostosta
   */
  public String
  readFromFileByUsingReadCharacterSet(String readFileName)
  throws FileNotFoundException, IOException //, Exception
  {
     String msg = "Avataan tiedostoa: " + readFileName;
     if (logger != null)
         logger.info(msg);

     File f = new File(readFileName);
     return readFromFileByUsingReadCharacterSet(f);
  }

  public String
  readFromFileByUsingReadCharacterSet(File file)
  throws FileNotFoundException, IOException //, Exception
  {
        //try {
          String msg = "Avataan tiedostoa: " + file.getAbsolutePath();
           if (logger != null)
           logger.info(msg);
          
           return readFromFileByUsingReadCharacterSet(new FileInputStream(file));           
  }

  public String
  readFromFileByUsingReadCharacterSet(FileInputStream fis)
  throws FileNotFoundException, IOException //, Exception
  {
        //try {
            //fr = new FileReader (f);
            InputStreamReader isr = new InputStreamReader(
                     fis, strFromCharacterSet.toString().replace('_','-')
                     );
       return readFromFileByUsingReadCharacterSet(isr);
  }

  public String
  readFromFileByUsingReadCharacterSet(InputStreamReader isr)
  throws FileNotFoundException, IOException //, Exception
  {
        //try {
            BufferedReader reader = new BufferedReader (isr);
            String result = reader.readLine();
            if (result == null)
        return null;
     
            StringBuffer ml4Data = new StringBuffer();               
            while(result != null)
            {     
        ml4Data.append(result +"\n");
        result = reader.readLine();       
            }
         
            reader.close();
            isr.close();           
           
            return ml4Data.toString();
            /*
          } catch ( Exception e){
            e.printStackTrace();
            throw e;
          }
          */       
  }

  public static ByteArrayOutputStream
  readMixed88591AndUTF8FileAndConvertIntoUTF8(String fileName)
  throws DecoderCharacterSetException, CharacterCodingException, UnsupportedEncodingException, IOException
  {
    String modified = readMixed88591AndUTF8FileConvertIntoUTF8(fileName);
    if (modified == null)
      return null;
    ByteArrayOutputStream resultstream = new ByteArrayOutputStream();
    resultstream.write(modified.getBytes());
    return resultstream;
  }
 
  /**
   * Tämä methodi lukee tiedoston sisällän, jonka merkistässä
   * on UTF_8 sekä ISO_8859_1 merkkejä sekaisin. Luetaan tiedoston
   * sisältä molemmilla merkistäillä ja verrataan niitä keskenään.
   * Palautetaan tiedoston sisältä vertailun jälkeen UFT:na.
   *
   * @param fileName Luettava tiedosto, jossa sekaisin uft-8:aa ja Latin 1:sta
   * @return Verrattu ja muutetut merkit, ks yllä.
   * @throws DecoderCharacterSetException
   * @throws CharacterCodingException Virhe, ei tuettu merkkistämuunnos
   * @throws UnsupportedEncodingException Virhe, ei tuettu merkkistämuunnos
   * @throws FileNotFoundException Virhe, ei tietostoa
   * @throws IOException Virhe, tiedostoluku- tai -kirjoitusvirhe
   */
  public static String
  readMixed88591AndUTF8FileConvertIntoUTF8(String fileName)
  throws   DecoderCharacterSetException,
      CharacterCodingException,
      UnsupportedEncodingException,
      FileNotFoundException,
      IOException
  {
    if (fileName == null || fileName.trim().length() == 0)
      return null;
    DecoderCharacterSet.CHARACTERSET writeCharacterSet_utf8 =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.UTF_8);
    DecoderCharacterSet.CHARACTERSET readCharacterSet_latin1 =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.ISO_8859_1);
    DecoderCharacterSet.CHARACTERSET writeCharacterSet_latin1 =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.ISO_8859_1);
    DecoderCharacterSet.CHARACTERSET readCharacterSet_utf8 =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.UTF_8);
   
    DecoderCharacterSet latin1Coder =
      new DecoderCharacterSet( readCharacterSet_latin1,  writeCharacterSet_utf8);
    /*
    DecoderCharacterSet utf8Coder =
      new DecoderCharacterSet( readCharacterSet_utf8,  writeCharacterSet_latin1);
    */
    DecoderCharacterSet utf8Coder =
      new DecoderCharacterSet( readCharacterSet_utf8,  writeCharacterSet_utf8);

    if (logger != null)
      logger.info("Avataan tiestoa: " + fileName);

      // luetaan tiedosto ISO_8859_1- sekä UTF_8-merkkeinä:
    String readedFileContentIn8859_1 =
      latin1Coder.readFromFileByUsingReadCharacterSet(fileName);
    String readedFileContentInUTF_8 =
      utf8Coder.readFromFileByUsingReadCharacterSet(fileName);
    return   readMixed88591AndUTF8FileConvertIntoUTF8(
        readedFileContentIn8859_1,
        readedFileContentInUTF_8);

  }   

  /**
   * Tämä methodi lukee tiedoston sisällän, jonka merkistässä
   * on UTF_8 sekä ISO_8859_1 merkkejä sekaisin. Luetaan tiedoston
   * sisältä molemmilla merkistäillä ja verrataan niitä keskenään.
   * Palautetaan tiedoston sisältä vertailun jälkeen UFT:na.
   *
   * @param fileName Luettava tiedosto, jossa sekaisin uft-8:aa ja Latin 1:sta
   * @return Verrattu ja muutetut merkit, ks yllä.
   * @throws DecoderCharacterSetException
   * @throws CharacterCodingException Virhe, ei tuettu merkkistämuunnos
   * @throws UnsupportedEncodingException Virhe, ei tuettu merkkistämuunnos
   * @throws FileNotFoundException Virhe, ei tietostoa
   * @throws IOException Virhe, tiedostoluku- tai -kirjoitusvirhe
   */
  public static String
  readMixed88591AndUTF8FileConvertIntoUTF8(InputStreamReader isr)
  throws   DecoderCharacterSetException,
      CharacterCodingException,
      UnsupportedEncodingException,
      FileNotFoundException,
      IOException
  {
    if (isr == null)
      return null;
    DecoderCharacterSet.CHARACTERSET writeCharacterSet =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.UTF_8);
    DecoderCharacterSet.CHARACTERSET readCharacterSet =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.ISO_8859_1);

    DecoderCharacterSet latin1Coder =
      new DecoderCharacterSet( readCharacterSet,  writeCharacterSet);
    writeCharacterSet =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.ISO_8859_1);
    readCharacterSet =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.UTF_8);
    DecoderCharacterSet utf8Coder =
      new DecoderCharacterSet( readCharacterSet,  writeCharacterSet);

      // luetaan tiedosto ISO_8859_1- sekä UTF_8-merkkeinä:
    String readedFileContentIn8859_1 =
      latin1Coder.readFromFileByUsingReadCharacterSet(isr);
    String readedFileContentInUTF_8 =
      utf8Coder.readFromFileByUsingReadCharacterSet(isr);
    return   readMixed88591AndUTF8FileConvertIntoUTF8(
        readedFileContentIn8859_1,
        readedFileContentInUTF_8);

  }

  /**
   * Tämä lukee parametriensa merkkijonot, joiden sisältää toisiinsa.
   * Parametrien sisällät oltava loogisesti samat, sillä erotuksella,
   * että toinen on luettu UFT8:na ja toinen on luettu ISO_8859_1:na.
   *  , jonka merkistässä
   * on UTF_8 sekä ISO_8859_1 merkkejä sekaisin. Luetaan tiedoston
   * sisältä molemmilla merkistäillä ja verrataan niitä keskenään.
   *
   * @param strContentIn8859_1
   * @param strContentInUTF_8
   * @return
   * @throws DecoderCharacterSetException
   * @throws UnsupportedEncodingException
   */
  public static String
  readMixed88591AndUTF8FileConvertIntoUTF8(
      String strContentIn8859_1,
      String strContentInUTF_8)
  throws   DecoderCharacterSetException,
      UnsupportedEncodingException
  {
      //try {
   
    int maxInd8859_1 = strContentIn8859_1.length();
    int maxIndUTF_8 = strContentInUTF_8.length();
    int ind8859_1 = 0, indUTF_8 = 0, iStrUTF8length,
      iChUTF_8, new_ind8859_1,
      iNext_ch8859_1, iCompareCh,
      iCh8859_1;
    char chUTF_8 = 0, ch8859_1 = 0,
       saveCh, new_ch8859_1,
       compareCh, next_ch8859_1;
   
    String strUTF8;
    boolean bSavedChSet = false;
   
    StringBuffer sbUTF_8 = new StringBuffer(maxIndUTF_8);
   
    // pidetään utf-8 dataa parempana, jossa tarvittaessa siirretään
    // ind8859_1 1 tai enemmän ylimääräistä eteen päin, mikäli
    // 1 utf-8 merkki esitetään 8859_1:ssa 2 tai useampaa merkkiä
    for(indUTF_8 = 0; indUTF_8 < maxIndUTF_8; indUTF_8++, ind8859_1++)
    {
      saveCh = (char)0;
      bSavedChSet = false;
      chUTF_8 = strContentInUTF_8.charAt(indUTF_8);
      iChUTF_8 = ((int)chUTF_8); // vastaava int arvo
      ch8859_1 = strContentIn8859_1.charAt(ind8859_1);
      iCh8859_1 = ((int)ch8859_1); // vastaava int arvo
     
      if (chUTF_8 == 65533 && ch8859_1 != chUTF_8)
      {// konversio ei ole onnisunut
        saveCh = ch8859_1; // oikea merkki 8859_1:ssa
        bSavedChSet = true;
      }
      else
      if (chUTF_8 < 128)
      { // merkistät tässä samat
        saveCh = chUTF_8; // ok char
        bSavedChSet = true;
      }
      else
      {
        if (ch8859_1 == 65533)
        { // ei pystytty muuntamaan 8859_1-merkkiä
          saveCh = chUTF_8; // ok char
          bSavedChSet = true;
        }
        else
        {
          // tutkitaan onko utf-8 merkki pitempi kuin 1 merkki 8859_1:na pitempi kuin 1
          // eli viekä merkki enemmän kuin 1 tavua 8859_1:na:
          strUTF8 = new String(Character.valueOf(chUTF_8).toString().getBytes(DecoderCharacterSet.UTF_8));
          iStrUTF8length =  strUTF8.length();
          if (iStrUTF8length > 1)
          {  // 2 tai enemmän tavua kun merkki esitetään 8859_1:nä
           
            int tmp_88591_end = ind8859_1+10;
            if (tmp_88591_end > maxInd8859_1)
              tmp_88591_end = maxInd8859_1;
            if (bDebug)
            {
              int tmp_utf8_end = indUTF_8+20;
              if (tmp_utf8_end > maxIndUTF_8)
                tmp_utf8_end = maxIndUTF_8;
              int tmp_utf8_start = indUTF_8-20;
              if (tmp_utf8_start > 0)
                tmp_utf8_start = 0;
              String tmp_88591 = strContentIn8859_1.substring(ind8859_1, tmp_88591_end);
              String tmp_utf8 = strContentInUTF_8.substring(tmp_utf8_start, tmp_utf8_end);
            }
           
            // siirretään 8859_1 indeksi sen merkin loppuun, mikä on 8859_1-datan
            // kyseisen 8859_1:n merkkiä vastaavan merkkijonon viimeiseksi:
            new_ind8859_1 = ind8859_1 + iStrUTF8length-1;
            if (new_ind8859_1 > maxInd8859_1) //  tarkistetaan ettei yli 8859_1:n
              new_ind8859_1 = maxInd8859_1 - 1; // indeksin yli
            new_ch8859_1 = strContentIn8859_1.charAt(new_ind8859_1);
            next_ch8859_1 = strContentIn8859_1.charAt(new_ind8859_1+1);
            iNext_ch8859_1 = new_ch8859_1; // vastaava int arvo
            if (bDebug)
            {
              int tmp2_88591_end = new_ind8859_1+10;
              if (tmp2_88591_end > maxInd8859_1)
                tmp2_88591_end = maxInd8859_1;
              String tmp1_88591 = strContentIn8859_1.substring(new_ch8859_1, tmp_88591_end);
              String tmp2_88591 = strContentIn8859_1.substring(new_ind8859_1, tmp2_88591_end);
            }
           
            // muunnetaan viimeisen merkin merkki 8859_1-vastaavaksi merkiksi,
            // että voidaan vertailla:
            compareCh = new String(Character.valueOf(strUTF8.charAt(
                iStrUTF8length-1)).toString().getBytes(DecoderCharacterSet.ISO_8859_1)).charAt(0);
            iCompareCh = compareCh;   
            // jos yllä oleva muunnos ei onnistu, compareCh on '?'
            // jos ei ole ?-merkki ja merkeissä eroa, on jonkinlainen virhe:
            if (bDebug && new_ch8859_1 != 65533
              && compareCh != '?' )
            {
              int tmp_ind = new_ind8859_1 + iStrUTF8length;
              if (tmp_ind > maxInd8859_1)
                tmp_ind = maxInd8859_1;
              String vastaava_88591 = strContentIn8859_1.substring(ind8859_1, new_ind8859_1);
              if (vastaava_88591 != null && !vastaava_88591.equals(strUTF8))
              {
                String tmp3_88591 = strContentIn8859_1.substring(ind8859_1-20, ind8859_1+20);
                throw new DecoderCharacterSetException(
                  "8859_1-merkit eivät vastaa utf-8:n merkkiä koodattuna 8859-1!= strUTF8.charAt(iStrUTF8length-1)!"
                  +" kohta: '" + tmp3_88591 +"'");
              }
            }
            // siirrä 8859_1-indeksi uuteen paikkaan, koska 1 utf-8 merkkiä vastaa
            // useampi 8859_1-merkki
            ind8859_1 = new_ind8859_1;
            ch8859_1 = new_ch8859_1;
          }
        }
        // muunna lyhyt välilyönti ja erik.lainausmerkki tavallisiksi:
        saveCh = changeSpecialChars(chUTF_8); // oikea merkki UTF_8, ok char
        bSavedChSet = true;
      }     
      if (!bSavedChSet) // merkkiä ei ole yllä asetettu, logiikka ongelma
        throw new DecoderCharacterSetException("SavedChSet is not set!");
      sbUTF_8.append(saveCh);
    }
      //} catch (Exception e){
        //e.printStackTrace();
        //throw e;
      //}
      return sbUTF_8.toString();
    }

  public static String
  getDataOfUTF8File(String fileName)
  throws DecoderCharacterSetException, FileNotFoundException, IOException
  {
   DecoderCharacterSet.CHARACTERSET readCharacterSet_utf8 =
      DecoderCharacterSet.getCharacterSet(DecoderCharacterSet.UTF_8);

   DecoderCharacterSet utf8Coder = 
      new DecoderCharacterSet( readCharacterSet_utf8,  readCharacterSet_utf8);

   String readedFileContentInUTF_8 = 
      utf8Coder.readFromFileByUsingReadCharacterSet(fileName);
   return readedFileContentInUTF_8;
  }

  /**
   * Tämä lukee parametriensa merkit ja palauttaa indeksi arvon ensimmäisestä
   * löytyneestä ei tunnistetusta merkistä (merkin arvo = 65533).
   *
   * @param strContentInUTF_8 Data
   * @return indeksi arvo, joka osoittaa ensimmäiseen löytyneeseen ei
   * tunnistetttuun merkkiin. Jos palauttaa -1, merkit merkkijonossa Javan
   * tunnistamia.
   */
  public static int []
  indArrayOfContainsNonUTF8Chars(String strContentInUTF_8)
  {
    int iStart = 0;
    int ind = indContainsNonUTF8Chars(strContentInUTF_8, iStart);
    if(ind == -1)
      return new int[0];
   
    List<Integer> indList = new ArrayList<Integer> ();   
    indList.add(ind);   
    int len = strContentInUTF_8.length();
   
    while(ind != -1)
    {
      if (ind < (len-1))
      {
        iStart = ind +1;
        ind = indContainsNonUTF8Chars(strContentInUTF_8, iStart);
        if (ind > -1)
          indList.add(ind);
      }
    }
   
    int max = indList.size();
    int intArray [] = new int[max];   
    for(int i = 0; i < max; i++)
      intArray[i] = indList.get(i);
     
    return intArray;
    }

  /**
   * Tämä lukee parametriensa merkit ja palauttaa indeksi arvon ensimmäisestä
   * löytyneestä ei tunnistetusta merkistä (merkin arvo = 65533).
   *
   * @param strContentInUTF_8 Data
   * * @param iStart Jos kutsutaan ensimmäistä kertaa, yleensä arvoksi annetaan 0
   *                 tai jos indArrayOfContainsNonUTF8Chars metodi kutsuu, se antaa arvon.
   * @return indeksi arvo, joka osoittaa ensimmäiseen löytyneeseen ei
   * tunnistetttuun merkkiin. Jos palauttaa -1, merkit merkkijonossa Javan
   * tunnistamia.
   */
  public static int
  indContainsNonUTF8Chars(String strContentInUTF_8, int iStart)
  {
    int maxIndUTF_8 = strContentInUTF_8.length();
    int indUTF_8 = 0,
      iChUTF_8;
    char chUTF_8 = 0;
           
    for(indUTF_8 = iStart; indUTF_8 < maxIndUTF_8; indUTF_8++)
    {
      chUTF_8 = strContentInUTF_8.charAt(indUTF_8);
      iChUTF_8 = ((int)chUTF_8); // vastaava int arvo
     
      if (chUTF_8 == 65533)
      {// konversio ei ole onnisunut
        return indUTF_8;
      }
    }
    return -1; // ok, vain utf-8, tai ainakin lukemisessa tavu menneet ok
    }

  /**
   * Tämä lukee parametriensa merkit ja palauttaa indeksi arvon ensimmäisestä
   * löytyneestä ei tunnistetusta merkistä (merkin arvo = 65533).
   *
   * @param strContentIn88591 Data
   * * @param iStart Jos kutsutaan ensimmäistä kertaa, yleensä arvoksi annetaan 0
   *                 tai jos indArrayOfContainsNonUTF8Chars metodi kutsuu, se antaa arvon.
   * @return indeksi arvo, joka osoittaa ensimmäiseen löytyneeseen ei
   * tunnistetttuun merkkiin. Jos palauttaa -1, merkit merkkijonossa Javan
   * tunnistamia.
   */
  public static int
  indContainsNon88591Chars(String strContentIn88591, int iStart)
  {  // kutsuu indContainsNonUTF8Chars-mehtodia, koska 8859-1
    // tulee myös merkin arvoksi 65533, kun sitä ei ole tulkittu
    // oikein 8859-1 merkiksi, vaan on esim utf-8 merkin tavut:
    return indContainsNonUTF8Chars(strContentIn88591, iStart);
  }
 
  /**
   * Tämä methodi palauttaa merkin, mutta muuttaa sen jos se on erikoismerkkien joukossa.
   * Esim muuntaa lyhyen välilyönti ja erik.lainausmerkin tavallisiksi:
   * Ks koodia.
   * @param ch Mahdoll. muutettava merkki
   * @return Ks yllä.
   */
  public static char
  changeSpecialChars(char ch)
  {
    if (8201 == ch) // # 'THIN SPACE' vaihdetaan tavuviivaksi:
      return ' ';
    else
    if (8221 == ch) // # 'erikois lainausmerkki' vaihdetaan ":ksi:
      return '"';
    return ch;
  }
 
  /**
   * Tämä methodi palauttaa merkijonon muutettuna, jos sen on erikoismerkkejä.
   * Ks koodia.
   * @param ch Mahdoll. muutettava merkki
   * @return Ks yllä.
   */
  public static String
  changeSpecialChars(String value)
  {
    if (value == null || value.trim().length() == 0)
      return value;
    int max = value.length();
    StringBuffer sp = new StringBuffer();
    for(int i = 0; i < max; i++)
      sp.append(changeSpecialChars(value.charAt(i)));
    return sp.toString();
  }

  /***
   * Tämä methodi on tarkoitettu varmistamaan, että kun konvertoidaan (decodaus)
   * dataa eli merkkijonoja Javan merkistästä toiseen, on ensin esim tiedostosta
   * luettava juuri samalla merkkikoodauksella kuin sitten vastaavan dataa
   * konvertoitaessa käytetään. Eli 1) kun ensin luodaan decoder-olio, jolle
   * kerrotaan mitä merkkikoodausta käytetään luettaessa ja mitä merkkikoodausta
   * kirjoitettaessa. 2) Sitten luetaan esim tällä methodilla data eli esim
   * tiedoston sisältä ja 3) lopuksi kutsutaan decoder-olion convertCharacterSetBytes
   * -mehtodia, jossa kyseisen datan muunnos tapahtuu, mikäli data on ensin luettu
   * tällä readFromFileByUsingReadCharacterSet-metodilla!
   * @param readFileName Luettavan tiedoston nimi
   * @return Luettu data tiedostosta
   */
  public void
  writeToFileByUsingToCharacterSet(String strContent, String writeFileName)
  throws FileNotFoundException, IOException //, Exception
  {
    writeToFileByUsingToCharacterSet(strToCharacterSet,
        strContent, writeFileName);
  }

  public static void
  writeToFileByUsingToCharacterSet(String strToCharacterSet, String strContent, String writeFileName)
  throws FileNotFoundException, IOException //, Exception
  {
        //try {
          String msg = "Kirjoitetaan tiedostoa: " + writeFileName;
        if (logger != null)
        logger.info(msg);
           
            File fo = new File(writeFileName);

             //try {              
               FileOutputStream fos = new FileOutputStream(fo)
               OutputStreamWriter bos = new OutputStreamWriter(fos, strToCharacterSet);

               //System.out.println("-->:" + modifiedContent +"<---");
               bos.write(strContent.toCharArray());          
               bos.flush();
               bos.close();
           if (logger != null)
             logger.info("Tiedosto " + writeFileName +" kirjoitettu ja suljettu.");
                 /*
             } catch ( Exception e){
             System.out.println("Tulostustiedoston avaus ei onnistunut: " + e.getMessage());
               e.printStackTrace();
               throw e;
             }
             */
  }

  /*
  public ByteArrayOutputStream
  checkAndConvertIntoWriteCharacterSet1(String strCheckThis)
  throws CharacterCodingException, UnsupportedEncodingException, IOException
  {
    if (strCheckThis == null || strCheckThis.trim().length() == 0)
      return null;
    byte [] convertedBytes;
    ByteArrayOutputStream resultstream = new ByteArrayOutputStream();
   
    CharBuffer in = CharBuffer.wrap(strCheckThis);
    ByteBuffer out = ByteBuffer.allocate(1000000);
    //CharBuffer out = CharBuffer.allocate(100000);
    //ByteBuffer in = ByteBuffer.wrap(strCheckThis.getBytes());
    boolean endOfInput = false;
    CoderResult coderResult = this.fromEncoder.encode(in, out, endOfInput);
    //CoderResult coderResult = this.toDecoder.decode(in, out, endOfInput);
   
    if (coderResult.isError())
    {
      int leng = coderResult.length();
      if (leng == 1)
        coderResult.throwException();
    }
    if (coderResult.isMalformed())
      coderResult.throwException();
    if (coderResult.isUnmappable())
      coderResult.throwException();
    if (coderResult.isOverflow())
      coderResult.throwException();
    if (coderResult.isUnderflow())
      coderResult.throwException();
   
    char ch = 0, prevCh = 0, resultCh;
    int iPrevCh =  -1, iCh, iResultCh;
    int max = strCheckThis.length();
    boolean notWriten = true, bContinue = false;
   
    for(int i = 0; i < max; i++)
    {
      ch = strCheckThis.charAt(i);
      iCh = ch;
      if (iPrevCh != -1)
      {
        iResultCh = getFromUTF8CharIntoNormalChar(prevCh, ch);
        bContinue = true;
        if (iResultCh == -1)
        {
          resultCh = prevCh;
          bContinue = false;         
        }
        else
        {
          notWriten = false;
          resultCh = (char)iResultCh;
        }
         
        if (bContinue)
        {
          String tmp = new Character(resultCh).toString();
          convertedBytes = tmp.getBytes();
        }
        else
          convertedBytes = new Character(resultCh).toString().getBytes();
        //convertedBytes = new Character(resultCh).toString().getBytes(strToCharacterSet);
        resultstream.write(convertedBytes);
        if (bContinue)
        {
          iPrevCh = -1;
          continue;
        }         
        notWriten = true;
      }       
      prevCh = ch;
      iPrevCh = prevCh;
    }
   
    if (notWriten)
    {
      convertedBytes = new Character(prevCh).toString().getBytes(strToCharacterSet);
      resultstream.write(convertedBytes);
    }
    //resultstream.write("ä".getBytes(UTF_8));
    //resultstream.write("ä".getBytes(ISO_8859_1));

    return resultstream;
  }
  */
 
  /*
  private int getFromUTF8CharIntoNormalChar(char prevCh, char ch)
  {
    if (prevCh == 195 && ch == 164 )
      return 'ä';
    return -1;
  }
  */
 
  /*
  public ByteArrayOutputStream
  checkAndConvertIntoWriteCharacterSet2(String strCheckThis)
  throws CharacterCodingException, UnsupportedEncodingException, IOException
  {
    if (strCheckThis == null || strCheckThis.trim().length() == 0)
      return null;

    arrayCharSetDecoders = new DecoderCharacterSet[maxArray];
       try {
         DecoderCharacterSet.CHARACTERSET writeCSet = getCharacterSet(this.strToCharacterSet);
         arrayCharSetDecoders[0] = new DecoderCharacterSet(
           getCharacterSet(UTF_8.toString().replace('_', '-')),
           writeCSet);
         arrayCharSetDecoders[1] = new DecoderCharacterSet(
           getCharacterSet(UTF_16.toString().replace('_', '-')),
           writeCSet);
         arrayCharSetDecoders[2] = new DecoderCharacterSet(
           getCharacterSet(UTF_16BE.toString().replace('_', '-')),
           writeCSet);
         arrayCharSetDecoders[3] = new DecoderCharacterSet(
           getCharacterSet(UTF_16LE.toString().replace('_', '-')),
           writeCSet);
         arrayCharSetDecoders[4] = new DecoderCharacterSet(
           getCharacterSet(ISO_8859_1.toString().replace('_', '-')),
           writeCSet);
         arrayCharSetDecoders[5] = new DecoderCharacterSet(
           getCharacterSet(US_ASCII.toString().replace('_', '-')),
           writeCSet);
       } catch (Exception e) {
         System.err.println(e.getMessage());
         e.printStackTrace();
       }

    int max = strCheckThis.length();
    char ch;
    int iCh;
    byte [] convertedBytes;
    ByteArrayOutputStream resultstream = new ByteArrayOutputStream();
   
    for(int i = 0; i < max; i++)
    {
      ch = strCheckThis.charAt(i);
      iCh = ch;
      //convertedBytes = this.getCharacterSetBytes(csdecoder, value, CR)
      if (isCharacterSetBytes(ch))
      {
        //convertedBytes = convertCharacterSetBytes(ch, null);
        convertedBytes = new Character(ch).toString().getBytes(strToCharacterSet);
        resultstream.write(convertedBytes);
      }
      else
      {
        //convertedBytes = convertFromNotFromCharacterSet(ch);
        convertedBytes = new Character(ch).toString().getBytes(strToCharacterSet);
        resultstream.write(convertedBytes);
      }
    }
    //resultstream.write("ä".getBytes(UTF_8));
    //resultstream.write("ä".getBytes(ISO_8859_1));

    return resultstream;
  }
  */
 
  /*
  private byte [] convertFromNotFromCharacterSet(char chConvertThis)
  throws CharacterCodingException, UnsupportedEncodingException
  {
    int max = arrayCharsetEncoders.length;
    for(int i = 0; i < max; i++)
    {
      if (isCharacterSetBytes(arrayCharsetEncoders[i], chConvertThis))
      {
       
        byte [] bytes = convertCharacterSetBytes(arrayCharSetDecoders[i],
            new Character(chConvertThis).toString(), null);       
        if (bytes == null || bytes.length == 0)
          return null;
        // jostain syystä tulee ylimääräinen 0 viimeisenä alkiona
        // vaikka pitäisi tulla 2 bytes'ä:
        if (bytes.length > 1 && bytes[bytes.length-1] == 0)
        {
          byte [] tmp_bytes = new byte[bytes.length-1];
          int max2 = bytes.length-1;
          for(int j = 0; j < max2; j++)
            tmp_bytes[j] = bytes[j];
          //return new String(new String(tmp_bytes).getBytes(CS));
          String test =  new String(new String(tmp_bytes).getBytes(arrayCharSetDecoders[i].strFromCharacterSet));
          //String test2 =  new String(new Character(chConvertThis).toString().getBytes(
            //  arrayCharSetDecoders[i].toString()), arrayCharSetDecoders[i].toString());
          return test.getBytes();
        }
        return bytes;
        //return new String(bytes).getBytes(), CS);
      }
    }
    byte [] bytes = convertCharacterSetBytes(chConvertThis, null);
    return bytes;
  }
  */

  /**
   * Tämä methodi palauttaa developerin käyttämän merkkistämerkkijonon
   * luokan vastaavan arvon. Eli tämän luokan merkistäjen constit
   * @param writeWithCharSet
   * @return Ks yllä.
   * @throws Exception
   */
  public static DecoderCharacterSet.CHARACTERSET  
  getCharacterSet(String writeWithCharSet)
  throws DecoderCharacterSetException
  {
        if (writeWithCharSet == null)
        throw new DecoderCharacterSetException("Väärä character set: "
            + writeWithCharSet);
        else // varmuuden vuoksi korvataan _:t -:ksi jos niitä on
      if (writeWithCharSet.equalsIgnoreCase(UTF_8.replace('_', '-')) )
        return DecoderCharacterSet.CHARACTERSET.UTF_8;
        else
      if (writeWithCharSet.equalsIgnoreCase(UTF_16.replace('_', '-')) )
        return DecoderCharacterSet.CHARACTERSET.UTF_16;
        else
      if (writeWithCharSet.equalsIgnoreCase(UTF_16BE.replace('_', '-')) )
        return DecoderCharacterSet.CHARACTERSET.UTF_16BE;
        else
      if (writeWithCharSet.equalsIgnoreCase(UTF_16LE.replace('_', '-')))
        return DecoderCharacterSet.CHARACTERSET.UTF_16LE;
      else
      if (writeWithCharSet.equalsIgnoreCase(ISO_8859_1.replace('_', '-')))
        return DecoderCharacterSet.CHARACTERSET.ISO_8859_1;
      else
      if (writeWithCharSet.equalsIgnoreCase(US_ASCII.replace('_', '-')))
        return DecoderCharacterSet.CHARACTERSET.US_ASCII;
      else
        throw new DecoderCharacterSetException("Väärä character set: "
              + writeWithCharSet);
  }
 
   public static void main(String [] args   )
     {
    if (logger != null)
      logger.info("checkAndConvertIntoWriteCharacterSet");

        if   (args.length < 1)
        {
        usage();
          System.exit(1);
        }
        else
        {
             if (args.length > 4)
            {
             usage();
             System.exit(2);
            }
          try {
            if (args.length == 1)
              checkAndConvertIntoWriteCharacterSet(args[0], null, null, null  );
            else
               if (args.length == 2)
              checkAndConvertIntoWriteCharacterSet(args[0], args[1], null, null  );
            else
               if (args.length == 3)
                checkAndConvertIntoWriteCharacterSet(args[0], args[1], args[2], null );
            else
               if (args.length == 4)
                checkAndConvertIntoWriteCharacterSet(args[0], args[1], args[2], args[3]);
          }catch(Exception e){
            System.err.println("Virhe: " +e.getMessage() +"\n");
            e.printStackTrace();
            usage();
            System.exit(3);
          }
        }
         
     }

   public static void
   checkAndConvertIntoWriteCharacterSet(String fileName,
             String outFileName,
             String readWithCharSet,
             String writeWithCharSet)
   throws Exception
   {
      if (fileName == null)
      {
        String msg = "Lukutiedoston nimi on tyhjä!" ;
        if (logger != null)
          logger.severe(msg);
        return;
      }
     
      //StringBuffer sp = new StringBuffer ();
      if (writeWithCharSet == null)
        writeWithCharSet = readWithCharSet;
     
      if (readWithCharSet == null || readWithCharSet.trim().equals(""))
        readWithCharSet = defLanguage;
      if (writeWithCharSet == null || writeWithCharSet.trim().equals(""))
        writeWithCharSet = defLanguage;     
     
      System.out.println("luku-merkistä=" + readWithCharSet);
      System.out.println("kirjoitus-merkistä=" + writeWithCharSet);
     
      DecoderCharacterSet.CHARACTERSET writeCharacterSet =
            getCharacterSet(writeWithCharSet);
      DecoderCharacterSet.CHARACTERSET readCharacterSet =
        getCharacterSet(readWithCharSet);

      /*
      DecoderCharacterSet decoder = new DecoderCharacterSet( readCharacterSet,  writeCharacterSet);
          // DecoderCharacterSet.CHARACTERSET.UTF_8.toString().replace('_','-')
      */
      ByteArrayOutputStream modifiedContent = null;
     
      try {
        System.out.println("Avataan tiestoa: " + fileName);       
        modifiedContent = readMixed88591AndUTF8FileAndConvertIntoUTF8(fileName);
       
      } catch ( Exception e){
        e.printStackTrace();
      }

      try {
        if (outFileName == null)
          System.out.println(modifiedContent);
        else
        {
           try {
            
             System.out.println("Tulostetaan tiedostoa " + outFileName +" ... ");
             File fo = new File(outFileName);
             FileOutputStream fos = new FileOutputStream(fo)
             OutputStreamWriter bos = new OutputStreamWriter(fos, writeWithCharSet);

           System.out.println("-->:" + modifiedContent +"<---");
             bos.write(modifiedContent.toString().toCharArray());          
             bos.flush();
             bos.close();
               System.out.println("Merkistän muunnos valmis.");
           } catch ( Exception e){
           System.out.println("Tulostustiedoston avaus ei onnistunut: " + e.getMessage());
             e.printStackTrace();
             return;
           }
        }
      } catch ( Exception e){
        System.out.println("Virhe: " + e.getMessage());
          e.printStackTrace();
      }
   }

  /**
   * Tämä methodi palauttaa käyttäjärjestelmän mukaisen carriage
   * return merkkeinä. Eli unixilla \n, muuten \r\n
   * @return Ks yllä.
   */
  public static String getCarriageReturn()    
  {
    if (File.separatorChar == ':')
      return "\n";
    else
      return "\r\n";
  }

  /**
   * Tämä methodi palauttaa parametrin merkkijonon, jossa \n merkit
   * vaihdetaan käyttäjärjestelmän mukaisiksi carriage
   * return merkkeiksi. Eli unixilla \n, muuten \r\n
   * @param str Muunnettava merkkijono. Ks. yllä.
   * @return Muunnettu merkkijono. Ks. yllä.
   */
  public static String convertCRAfterOS(boolean bConvert, String str)    
  {
    if (str == null)
      return null;
    if (!bConvert)
      return str;
    return str.replaceAll("\n", getCarriageReturn());
  }

   private static void usage()
   {
       System.err.println("DtBook2ml4:n merkistän ämuunnosohjelma V. 1.1.1");
       System.err.println("Kaytto:" );
       System.err.println("" + DecoderCharacterSet.class +" muutettava_tiedosto tulostiedosto" );
       System.err.println(" - muunnos samaan tiedostoon tai:" );
       System.err.println("" + DecoderCharacterSet.class +" muutettava_tiedosto tulostiedosto [luku_charset]" );
       System.err.println(" - tulostus tiedostoon tai:" );
       System.err.println("" + DecoderCharacterSet.class +" muutettava_tiedosto tulostiedosto [luku_charset] [kirjoitus_charset]" );
       System.err.println(" - tulostus tiedostoon tai:" );
       System.err.println("" + DecoderCharacterSet.class +" muutettava_tiedosto" );
       System.err.println(" - tulostus näytälle" );      
       System.err.println(" - Käytetty oletus character setti on UTF-8" );
       System.err.println(" - Sallitut character setit ovat:" );
       System.err.println("   " + UTF_8 +", " + UTF_16+", " +
                     UTF_16BE+", " + UTF_16LE+", " +
                     ISO_8859_1+" ja " + US_ASCII);      
   }

   public static String
   getHexValue(String value)
   {
     if (value == null)
       return value;
    
    byte [] bytes = value.getBytes();
    int max2 = bytes.length;
    String strHexValue, strHex = "";
    StringBuffer sb = new StringBuffer ();
   
    for(int m = 0; m < max2; m++)
    {
      strHexValue = Integer.toString( (bytes[m] & 0xff) + 0x100, 16).substring(1);
      sb.append(strHexValue);
    }
  
    return sb.toString();
   }
}

TOP

Related Classes of fi.celia.convert.chars.DecoderCharacterSet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.