/*
 * Jakelib2 - General purpose C++ library
 * Copyright (C) 2001 Florian Wolff  (florian@donuz.de)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: ByteToCharConverter.h,v 1.18 2003/09/02 17:17:03 florian Exp $
 */

#ifndef INCLUDE_JAKELIB2_TEXT_ENC_BYTETOCHARCONVERTER_H
# define INCLUDE_JAKELIB2_TEXT_ENC_BYTETOCHARCONVERTER_H

namespace jakelib {
  namespace util {
    class CharArray;
  }
  namespace io {
    class InputStream;
  }
  namespace util {
    class Hashtable;
  }

  namespace text {
    namespace enc {


      /**
       * \c ByteToCharConverter is the abstract base class of all character
       * conversion classes that convert a sequence of bytes
       * (c-style string) into a sequence of unicode characters
       * (Jakelib-style string).
       *
       * Use \c getConverter() to get a converter for a certain
       * character encoding.
       *
       * All sub-classes should be thread-safe.
       *
       * Available encoding names:
       * \li ISO8859-1
       * \li ISO8859-2
       * \li ISO8859-3
       * \li ISO8859-4
       * \li ISO8859-5
       * \li ISO8859-6
       * \li ISO8859-7
       * \li ISO8859-8
       * \li ISO8859-9
       * \li ISO8859-10
       * \li ISO8859-11
       * \li ISO8859-13
       * \li ISO8859-14
       * \li ISO8859-15
       * \li UTF-8
       * \li ASCII
       * \li CP437
       * \li CP850
       *
       * @class ByteToCharConverter
       * @version $Id: ByteToCharConverter.h,v 1.18 2003/09/02 17:17:03 florian Exp $
       * @author Florian 'Overflo' Wolff (florian@donuz.de)
       */
      class ByteToCharConverter : public jakelib::lang::Object
	{
	public:

          /**
           * Creates a new \c ByteToCharConverter with a certain
           * character encoding name.
           */
	  ByteToCharConverter(char* characterEncoding);

          /**
           * Returns the name of the character encoding this
           * \c ByteToCharConverter implements.
           */
	  virtual jakelib::lang::String* getCharacterEncoding();

          /**
           * Returns a short string representation of this converter.
           */
	  jakelib::lang::String* toString();

          /**
           * Takes a number of bytes from an input stream
           * and converts them to unicode characters.
           *
           * Stops if the input stream ends or a given number of output
           * characters has been written.
           *
           * @param inputStream The input stream to read the input bytes from
           * @param output      Pointer to a \c jchar array where the output
           *                    will be written
           * @param len         Number of characters to be written.
           *                    \c output must provide enough space to
           *                    contain \c len characters
           * @return The number of characters that have actually been written.
           *         This does not necessarily equal the number of bytes read.
           */
	  virtual int convert(jakelib::io::InputStream* inputStream,
			      jchar* output, int len) = 0;

          /**
           * Returns the default \c ByteToCharConverter.
           *
           * @return An instance of \c ByteToCharISO8859_1
           */
	  static ByteToCharConverter* getDefault();

          /**
           * Returns a \c ByteToCharConverter for the given
           * character encoding.
           *
           * @param encoding Name of the desired encoding. For example:
           *                 - "\c ISO8859_1" == "\c latin1"
           *                 - "\c ISO8859_15" == "\c 8859_15" == "\c ibm923"
           *                 - "\c UTF8" == "\c utf-8"
           *                 - "\c ASCII"
           */
	  static ByteToCharConverter* getConverter(jakelib::lang::String* encoding);

          /**
           * Same as above.
           */
	  static ByteToCharConverter* getConverter(char* encoding);

          /**
           * Called by \c Object::initJakelib2().
           * Do not use otherwise.
           */
	  static void initConverters();

	private:

          /** Holds name (\c String) to converter (\c ByteToCharConverter) mapping. */
	  static jakelib::util::Hashtable* converters;

          /** The default converter (always \c ISO-8859-1). */
	  static ByteToCharConverter* defaultConverter;

          /** The name of this character encoding. */
	  jakelib::lang::String* characterEncoding;

	  JAKELIB_DECLARE_CLASS(ByteToCharConverter);
	};
    }
  }
}

#endif
