// Revision: 36 1.15.1.4 source/core/text/intl/transcod/itrancod.hpp, text, ioc.v400, 980918 
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//      itrancod.hpp
//
//  This file has classes that provide character encodings conversion to and from Unicode.
//
//  The Transcoder Framework provides the facility to convert simple text strings
//  (e.g. char*) such as ISO Latin 8859 or any of the multitude of IBM or
//  Microsoft code pages to and from the Unicode character set used in the
//  Open Class framework environment..
//
//  IBM Open Class Library
//  (C) Copyright International Business Machines Corporation 1997
//  Licensed Material - Program-Property of IBM - All Rights Reserved.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#ifndef _ITRANCOD_
#define _ITRANCOD_

#include <stddef.h>

#include <iexcbase.hpp>
#include <istring.hpp>
#include <iprimtyp.hpp>
#include <itext.hpp>
#include <ilocale.hpp>
#include <icodecvt.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma enum(4)
#pragma pack(push,4)

//========================================================================================
// CLASS ITranscoder
// The main class that provide character encodings conversion to and from Unicode.
//========================================================================================
class ITranscoder {
public:
    //--------------------------------------------------------------
    // typedefs and enum definitions
    //--------------------------------------------------------------

    typedef     codecvt_base::result    result;
    typedef size_t                              length_type;

        // specifies how to handle unmapped characters
    enum EUnmappedBehavior {
        kUseSub,        // use substitution character
        kStop,          // stop conversion
        kOmit           // omit the character
        };

    enum EMappingProximity {
        kExactMapping = 0,      // create transcoder that exactly matches specified char set
        kSupersetMapping,       // create transcoder for a superset of specified char set
        kCloseMapping           // create transcoder for a char set that is close to the specified one
        };

    //-----------------------------------------------------------------
    // Transcoder object factory functions and destructor
    //-----------------------------------------------------------------

    virtual                     ~ITranscoder();

    static ITranscoder* createTranscoder(const IText& charSet,
                                        EMappingProximity proximity = kSupersetMapping);
    static ITranscoder* createTranscoder();

    //-----------------------------------------------------
    // Exception character handling functions
    //-----------------------------------------------------

    virtual EUnmappedBehavior   unmappedBehavior();
    virtual void            setUnmappedBehavior(EUnmappedBehavior unmappedBehavior);

    virtual char            charSubstitute();
    virtual void            setCharSubstitute(char substitute);
    virtual UniChar     uniCharSubstitute();

    //---------------------------------------------------
    // Transcoder state managemet functions
    //---------------------------------------------------

    virtual void        resetState();
    virtual result      flush(const char* to, const char* to_limit, char*& to_next);

    //------------------------------------------------------
    // High-level code set conversion functions
    //------------------------------------------------------

    virtual result      toUnicode(const IString& from, IText& to);

    virtual result      fromUnicode(const IText& from, IString& to);

    //-------------------------------------------------------------------
    // Low-level/pointer-based code set conversion functions
    //-------------------------------------------------------------------

    virtual result      toUnicode(const IString& from,
                            UniChar* to, UniChar* to_limit, UniChar*& to_next);
    virtual result      toUnicode(const char* from, const char* from_end,
                            const char*& from_next, IText& to);
    virtual result      toUnicode(const char* from, const char* from_end,
                            const char*& from_next,
                            UniChar* to, UniChar* to_limit, UniChar*& to_next);

    virtual result      fromUnicode(const UniChar* from, const UniChar* from_end,
                            const UniChar*& from_next, IString& to);
    virtual result      fromUnicode(const IText& from,
                            char* to, char* to_limit, char*& to_next);
    virtual result      fromUnicode(const UniChar* from, const UniChar* from_end,
                            const UniChar*& from_next,
                            char* to, char* to_limit, char*& to_next);

    //------------------------------
    // Query functions
    //------------------------------

    virtual IText       characterEncoding() const;
    static const IText  characterSet(const ILocaleKey& key);

    virtual length_type     maximumBytesPerUniChar() const = 0;
    virtual length_type     maximumUniCharsPerByte() const = 0;

    virtual length_type     byteBufferSize(const IText& uniText) const = 0;
    virtual length_type     byteBufferSize(const UniChar* from, const UniChar* from_end) const = 0;

    virtual length_type     uniCharBufferSize(const IString& text) const = 0;
    virtual length_type     uniCharBufferSize(const char* from, const char* from_end) const = 0;

protected:
    //--------------------------------------------------------------
    // Transcoder constructors and assignment operator
    //--------------------------------------------------------------

    ITranscoder();
    ITranscoder(const ITranscoder& source);

    ITranscoder&            operator=(const ITranscoder& right);

    //-------------------------------------------------------
    // Transcoder subclass conversion functions
    //-------------------------------------------------------

    virtual result      doToUnicode(const char* from, const char* from_end,
                            const char*& from_next,
                            UniChar* to, UniChar* to_limit, UniChar*& to_next) = 0;

    virtual result      doFromUnicode(const UniChar* from, const UniChar* from_end,
                            const UniChar*& from_next,
                            char* to, char* to_limit, char*& to_next) = 0;

    virtual void            setCharacterEncoding(const IText& encoding);

private:
    // For exception character handling
    EUnmappedBehavior   fUnmappedBehavior;
    char                            fCharSubstitute;
    UniChar                     fUniCharSubstitute;

    IText                           fCharacterEncoding;
};


//========================================================================================
// CLASS ICharacterSetIterator
// Provides APIs to iterate through the foreign codesets.
//========================================================================================
class ICharacterSetIterator {
public:
    //---------------------------------------------------
    // Constructors and assignment operator
    //---------------------------------------------------

    ICharacterSetIterator();
    ICharacterSetIterator(const ICharacterSetIterator& source);

    ICharacterSetIterator& operator=(const ICharacterSetIterator& right);

    virtual                                 ~ICharacterSetIterator();

    //---------------------------------------------------
    // Validate an iterator
    //---------------------------------------------------
    operator                                bool() const;

    //---------------------------------------------------
    // Cursor actions
    //---------------------------------------------------
    const IText                         operator*();            // returns the current character set

    ICharacterSetIterator&      operator++();
    ICharacterSetIterator       operator++(int);

    void                                        reset();

    //---------------------------------------------------
    // Comparison operator
    //---------------------------------------------------
    bool                                        operator==(const ICharacterSetIterator& right) const;
    bool                                        operator!=(const ICharacterSetIterator& right) const;

private:
    int                             fCurCharSetIdx;
};


//========================================================================================
// CLASS ILineBreakConverter
// This class is used to process the line breaking conventions for code set conversion.
//========================================================================================
class ILineBreakConverter {
public:
    enum ELineBreakConvention {
        kUnicode,       // Unicode line break convention
        kCRLF,          // Win, OS/2, DOS line break convention
        kLF,            // UNIX line break convention
        kCR,            // Macintosh line break convention
        kCRLF_VT,       // Microsoft Word/RichEdit line break convention
        kHost           // Current host line break convention
    };

    static void     convertInPlace(IText& string, ELineBreakConvention target = kUnicode);
    static IText    convert(const IText& string, ELineBreakConvention target = kUnicode);

    static ELineBreakConvention hostConvention();

private:
};

#pragma pack(pop)
#pragma enum(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _ITRANCOD_
