/*
 Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License, version 2.0,
 as published by the Free Software Foundation.

 This program is also distributed with certain software (including
 but not limited to OpenSSL) that is licensed under separate terms,
 as designated in a particular file or component or in included license
 documentation.  The authors of MySQL hereby grant you an additional
 permission to link the program and your derivative works with the
 separately licensed software that they have included with MySQL.

 This program 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 General Public License, version 2.0, for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
*/
/*
 * CharsetMap.hpp
 */

#ifndef CharsetMap_hpp
#define CharsetMap_hpp

/*
 * This API uses the C99 exact-width type aliases as defined in <stdint.h>.
 * Unfortunately, some C/C++ compiler still lack a stdint.h header file.
 * (For instance, MS Visual Studio until VS2010.)
 *
 * Since this API has no dependency upon NDBAPI, we do not want to use
 * the exact-width type aliases from there but delegate to a generic helper
 * file that handles the absence of the <stdint.h>.
 */
#include "mystdint.h"

/**
 * Handles encoding issues for character data
 * while keeping MySQL's CHARSET_INFO structure hidden.
 */
class CharsetMap {
public:

    CharsetMap();
    /* The compiler-generated destructor is OK. */
    /* The compiler-generated copy constructor is OK. */
    /* The compiler-generated assignment operator is OK. */

    /**
     * Initializes any global CharsetMap resources.
     * Should be called exactly once before any other CharsetMap function
     * from a single thread.
     */
    static void init();

    /**
     * Releases all global CharsetMap resources.
     * Also not thread-safe
     */
    static void unload();

    /**
     * Returns a standard character set name.
     *
     * The cs_number argument in getName(), getMysqlName(), and recode()
     * can be obtained from NdbDictionary::Column::getCharsetNumber().
     *
     * getName() returns a name that in most cases will be a preferred name
     * from http://www.iana.org/assignments/character-sets and will
     * be recognized and usable by Java (e.g. java.nio, java.io, and java.lang).
     * However it may return "binary" if a column is BLOB / BINARY / VARBINARY,
     * or it may return the name of an obscure MySQL character set such as
     * "keybcs2" or "dec8". 
     */
    const char * getName(int cs_number) const;

    /**
     * Returns just the internal mysql name of the charset.
     */
    const char * getMysqlName(int cs_number) const;

    /**
     * Takes the mysql name (not the standardized name) and returns a
     * character set number.
     */
    int getCharsetNumber(const char *mysql_name) const;

    /**
     * Convenience function for UTF-8.
     */
    int getUTF8CharsetNumber() const;

    /**
     * Convenience function for UTF-16.
     */
    int getUTF16CharsetNumber() const;

    /**
     * The return status of a buffer recode operation.
     */
    enum RecodeStatus {
        RECODE_OK ,
        RECODE_BAD_CHARSET ,
        RECODE_BAD_SRC ,
        RECODE_BUFF_TOO_SMALL
    };
    
    /**
     * Returns true if this charset number refers to a multibyte charset;
     * otherwise false.
     */
  const bool * isMultibyte(int cs_number) const;

    /**
     * Recodes the content of a source buffer into destination buffer.
     *
     * Takes five arguments:
     * lengths is an array of two ints: first the source
     *  buffer length, then the destination buffer length.
     * From and To are character set numbers.
     *  src and dest are buffers.
     *
     * On return, lengths[0] is set to the number of bytes consumed from src
     * and lengths[1] to the number of bytes written to dest.
     *
     * The string in src will be recoded from charset cs_from to charset cs_to.
     * If the conversion is successful we return RECODE_OK.
     * Other return values are noted above.
     */
    RecodeStatus recode(int32_t *lengths /* IN/OUT */,
                        int cs_from, int cs_to, const void *src,
                        void *dest) const;
                        
};

#endif // CharsetMap_hpp
