/** @name cp2ucnvrt.cpp
-----------------------------------------------------------------------------

 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.

-----------------------------------------------------------------------------

   Description: This file contains class CodePage2UnicodeConverter

-----------------------------------------------------------------------------


   5/21/1999  Initial creation

-------------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Include dependencies                                              */
/* ----------------------------------------------------------------------- */

#include "uima/u2cpcnvrt.hpp"

#include "uima/comp_ids.h"

#include "uima/assertmsg.h"
#include "uima/trace.hpp"
#include "uima/msg.h"


/* ----------------------------------------------------------------------- */
/*       Constants                                                         */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Forward declarations                                              */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Types / Classes                                                   */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Private Implementation                                            */
/* ----------------------------------------------------------------------- */

/* ----------------------------------------------------------------------- */
/*       Implementation                                                    */
/* ----------------------------------------------------------------------- */

namespace uima {

  Unicode2CodePageConverter::Unicode2CodePageConverter(const char * crConverterName) :
      iv_uconverter(NULL)
      /* ----------------------------------------------------------------------- */
  {
    UErrorCode err=(UErrorCode)0;
    iv_uconverter =  ucnv_open(crConverterName, &err);
    if (!U_SUCCESS(err)) {
      cerr << "CodePage2UnicodeConverter ERROR could not open converter for " << crConverterName << endl;
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_CODEPAGE_CONV_ERROR);
      errMsg.addParam(err);
      errMsg.addParam(crConverterName);
      UIMA_EXC_THROW_NEW(CodePageConversionException,
                         UIMA_ERR_CODEPAGE,
                         errMsg,
                         UIMA_MSG_ID_CODEPAGE_CONV_ERROR,
                         ErrorInfo::unrecoverable);
    }
    assert(iv_uconverter != NULL);
  }

  Unicode2CodePageConverter::~Unicode2CodePageConverter( ) {
     ucnv_close(iv_uconverter) ;
  }
  size_t Unicode2CodePageConverter::getMaximumSize(const UChar * cpclSource,
      size_t uiSourceLength) {
    size_t                     uiTargetSize;
    assert(iv_uconverter !=NULL);
    UErrorCode err=(UErrorCode)0;
    uiTargetSize =  ucnv_fromUChars(iv_uconverter, NULL,
                                    0, cpclSource, uiSourceLength, &err);

    if (!U_SUCCESS(err) &&  err != U_BUFFER_OVERFLOW_ERROR) {
      ///cerr << "ERROR getMaximumSize() " << err << endl;
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_CODEPAGE_CONV_ERROR);
      errMsg.addParam(err);
      UIMA_EXC_THROW_NEW(CodePageConversionException,
                         UIMA_ERR_CODEPAGE,
                         errMsg,
                         UIMA_MSG_ID_CODEPAGE_CONV_ERROR,
                         ErrorInfo::unrecoverable);
    }

    assert(sizeof(char) == 1);
    return(uiTargetSize);                              /* as bytes */
  }

  size_t Unicode2CodePageConverter::convertFromUnicode(char * pacTarget,
      size_t uiTargetMaxLength,
      const UChar * cpclSource,
      size_t uiSourceLength)
  /* ----------------------------------------------------------------------- */
  {
    size_t                     uiTargetSize;
    assert(iv_uconverter !=NULL);
    UErrorCode err=(UErrorCode)0;
    uiTargetSize =  ucnv_fromUChars(iv_uconverter, pacTarget,
                                    uiTargetMaxLength,
                                    cpclSource, uiSourceLength, &err);

    if (!U_SUCCESS(err) &&  err != U_BUFFER_OVERFLOW_ERROR) {
      ///cerr << "ERROR getMaximumSize() " << err << endl;
      ErrorMessage errMsg = ErrorMessage(UIMA_MSG_ID_CODEPAGE_CONV_ERROR);
      errMsg.addParam(err);
      UIMA_EXC_THROW_NEW(CodePageConversionException,
                         UIMA_ERR_CODEPAGE,
                         errMsg,
                         UIMA_MSG_ID_CODEPAGE_CONV_ERROR,
                         ErrorInfo::unrecoverable);
    }

    assert(sizeof(char) == 1);
    return(uiTargetSize);                              /* as bytes */
  }

}

/* <EOF> */


