home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Programming / ICU / src / icu / source / common / convert.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-19  |  11.6 KB  |  409 lines

  1.  
  2. /*******************************************************************************
  3. *                                                                              *
  4. * COPYRIGHT:                                                                   *
  5. *   (C) Copyright International Business Machines Corporation,  1998           *
  6. *   Licensed Material - Program-Property of IBM - All Rights Reserved.         *
  7. *   US Government Users Restricted Rights - Use, duplication, or disclosure    *
  8. *   restricted by GSA ADP Schedule Contract with IBM Corp.                     *
  9. *                                                                              *
  10. *******************************************************************************/
  11. /* C++ wrappers for the ICUs Codeset Conversion Routines*/
  12.  
  13. class Locale;
  14. class UnicodeString;
  15. class Mutex;
  16.  
  17. #include "utypes.h"
  18. #include "resbund.h"
  19. #include "cmemory.h"
  20. #include "mutex.h"
  21. extern "C" {
  22. #include "ucnv_io.h"
  23. #include "ucnv_bld.h"
  24. #include "ucnv.h"
  25. }
  26. #include "convert.h"
  27.  
  28.  
  29.  
  30. UnicodeConverterCPP::UnicodeConverterCPP()
  31. {
  32.     UErrorCode err = U_ZERO_ERROR;
  33.     myUnicodeConverter = ucnv_open(NULL, &err);
  34. }
  35. UnicodeConverterCPP::UnicodeConverterCPP(const char* name, UErrorCode& err)
  36. {
  37.     myUnicodeConverter = ucnv_open(name, &err);
  38. }
  39.  
  40. UnicodeConverterCPP::UnicodeConverterCPP(const UnicodeString& name, UErrorCode& err)
  41. {
  42.   char myName[UCNV_MAX_CONVERTER_NAME_LENGTH];
  43.   int i;
  44.   name.extract(0, i = name.size(), myName);
  45.   myName[i]='\0';
  46.   myUnicodeConverter = ucnv_open(myName, &err);
  47. }
  48.  
  49.  
  50. UnicodeConverterCPP::UnicodeConverterCPP(int32_t codepageNumber,
  51.                                          UConverterPlatform platform,
  52.                                          UErrorCode& err)
  53. {
  54.     myUnicodeConverter = ucnv_openCCSID(codepageNumber,
  55.                                    platform,
  56.                                    &err);
  57. }
  58.  
  59. UnicodeConverterCPP&   UnicodeConverterCPP::operator=(const UnicodeConverterCPP&  that)
  60. {
  61.     {
  62.         /*Decrements the overwritten converter's ref count
  63.          *Increments the assigner converter's ref count
  64.          */
  65.       Mutex updateReferenceCounters;
  66.       myUnicodeConverter->sharedData->referenceCounter--;
  67.       that.myUnicodeConverter->sharedData->referenceCounter++;
  68.     }
  69.  
  70.     *myUnicodeConverter = *(that.myUnicodeConverter);
  71.     return *this;
  72. }
  73.  
  74. bool_t UnicodeConverterCPP::operator==(const UnicodeConverterCPP& that) const
  75. {
  76.   if ((myUnicodeConverter->sharedData    == that.myUnicodeConverter->sharedData) &&
  77.       (myUnicodeConverter->fromCharErrorBehaviour == that.myUnicodeConverter->fromCharErrorBehaviour) &&
  78.       (myUnicodeConverter->toUnicodeStatus == that.myUnicodeConverter->toUnicodeStatus) &&
  79.       (myUnicodeConverter->subCharLen == that.myUnicodeConverter->subCharLen) &&
  80.       (icu_memcmp(myUnicodeConverter->subChar, that.myUnicodeConverter->subChar, myUnicodeConverter->subCharLen) == 0) &&
  81.       (myUnicodeConverter->UCharErrorBufferLength == that.myUnicodeConverter->UCharErrorBufferLength) &&
  82.       (myUnicodeConverter->charErrorBufferLength == that.myUnicodeConverter->charErrorBufferLength) &&
  83.       (icu_memcmp(myUnicodeConverter->UCharErrorBuffer, that.myUnicodeConverter->UCharErrorBuffer, myUnicodeConverter->UCharErrorBufferLength) == 0) &&
  84.       (icu_memcmp(myUnicodeConverter->charErrorBuffer, that.myUnicodeConverter->charErrorBuffer, myUnicodeConverter->charErrorBufferLength) == 0) &&
  85.       (myUnicodeConverter->fromUCharErrorBehaviour == that.myUnicodeConverter->fromUCharErrorBehaviour))
  86.   return TRUE;
  87.   else return FALSE;
  88. }
  89.  
  90. bool_t UnicodeConverterCPP::operator!=(const UnicodeConverterCPP& that) const
  91. {
  92.   return !(*this == that);
  93. }
  94.  
  95. UnicodeConverterCPP::UnicodeConverterCPP(const UnicodeConverterCPP&  that)
  96. {
  97.   /*increments the referenceCounter to let the static table know
  98.    *it has one more client
  99.    */
  100.     myUnicodeConverter = new UConverter;
  101.     {
  102.       Mutex updateReferenceCounter;
  103.       that.myUnicodeConverter->sharedData->referenceCounter++;
  104.     }
  105.     *myUnicodeConverter = *(that.myUnicodeConverter);
  106. }
  107.  
  108.  
  109. UnicodeConverterCPP::~UnicodeConverterCPP()
  110. {
  111.     ucnv_close(myUnicodeConverter);
  112. }
  113.  
  114.  void
  115. UnicodeConverterCPP::fromUnicodeString(char*                    target,
  116.                                        int32_t&                 targetSize,
  117.                                        const UnicodeString&     source,
  118.                                        UErrorCode&               err) const
  119. {
  120.   const UChar* mySource = NULL;
  121.   int32_t mySourceLength = 0;
  122.   UConverter myConverter;
  123.   char *myTarget = NULL;
  124.  
  125.   if (U_FAILURE(err)) return;
  126.  
  127.   if ((myUnicodeConverter == NULL) || source.isBogus() || (targetSize <= 0))
  128.     {
  129.       err = U_ILLEGAL_ARGUMENT_ERROR;
  130.       return;
  131.     }
  132.  
  133.   /*makes a local copy of the UnicodeConverter*/
  134.   myConverter = *myUnicodeConverter;
  135.  
  136.   /*Removes all state info on the UnicodeConverter*/
  137.   ucnv_reset(&myConverter);
  138.  
  139.  
  140.   mySourceLength = source.size();
  141.   mySource = source.getUChars();
  142.   myTarget = target;
  143.   ucnv_fromUnicode(&myConverter,
  144.                  &myTarget,
  145.                  target + targetSize,
  146.                  &mySource,
  147.                  mySource + mySourceLength,
  148.            NULL,
  149.            TRUE,
  150.                  &err);
  151.   targetSize = myTarget - target;
  152.  
  153.   return;
  154. }
  155.  
  156.  void
  157. UnicodeConverterCPP::toUnicodeString(UnicodeString&         target,
  158.                                      const char*            source,
  159.                                      int32_t                sourceSize,
  160.                                      UErrorCode&             err) const
  161. {
  162.   const char* mySource = source;
  163.   const char* mySourceLimit = source + sourceSize;
  164.   UChar* myTargetUChars = NULL;
  165.   UChar* myTargetUCharsAlias = NULL;
  166.   int32_t myTargetUCharsLength = 0;
  167.   UConverter myConverter;
  168.  
  169.   if (U_FAILURE(err)) return;
  170.   if ((myUnicodeConverter == NULL) || target.isBogus() || (sourceSize <= 0))
  171.     {
  172.       err = U_ILLEGAL_ARGUMENT_ERROR;
  173.       return;
  174.     }
  175.  
  176.   /*makes a local bitwise copy of the UnicodeConverter*/
  177.   myConverter = *myUnicodeConverter;
  178.  
  179.   /*Removes all state info on the UnicodeConverter*/
  180.   ucnv_reset(&myConverter);
  181.   /*Allocates the theoritically (Not counting added bytes from the error functions) max buffer
  182.    *on a "normal" call, only one iteration will be necessary.
  183.    */
  184.   myTargetUChars =
  185.     (UChar*)icu_malloc(sizeof(UChar)*(myTargetUCharsLength = (sourceSize/(int32_t)getMinBytesPerChar())));
  186.  
  187.   if (myTargetUChars == NULL)
  188.     {
  189.       err = U_MEMORY_ALLOCATION_ERROR;
  190.       return;
  191.     }
  192.   /*renders the target clean*/
  193.   target.remove();
  194.  
  195.   /*Will loop until (re-use the same buffer) until no more memory is requested
  196.    *or an error (other than INDEX_OUTOF_BOUNDS) is encountered
  197.    */
  198.   do
  199.     {
  200.       err = U_ZERO_ERROR;
  201.       myTargetUCharsAlias = myTargetUChars;
  202.       ucnv_toUnicode(&myConverter,
  203.                    &myTargetUCharsAlias,
  204.                    myTargetUChars + myTargetUCharsLength,
  205.                    &mySource,
  206.                    mySourceLimit,
  207.              NULL,
  208.              TRUE,
  209.              &err);
  210.  
  211.       /*appends what we got thus far to the UnicodeString*/
  212.       target.replace((UTextOffset)target.size(),
  213.              myTargetUCharsAlias - myTargetUChars,
  214.              myTargetUChars,
  215.              myTargetUCharsAlias - myTargetUChars);
  216.       /*Checks for the integrity of target (UnicodeString) as it adds data to it*/
  217.       if (target.isBogus()) err = U_MEMORY_ALLOCATION_ERROR;
  218.     } while (err == U_INDEX_OUTOFBOUNDS_ERROR);
  219.  
  220.  
  221.   icu_free(myTargetUChars);
  222.  
  223.   return;
  224. }
  225.  
  226.  
  227.  
  228. void
  229. UnicodeConverterCPP::fromUnicode(char*&                 target,
  230.                                  const char*            targetLimit,
  231.                                  const UChar*&        source,
  232.                                  const UChar*         sourceLimit,
  233.                  int32_t *offsets,
  234.                  bool_t                 flush,
  235.                                  UErrorCode&             err)
  236. {
  237.     ucnv_fromUnicode(myUnicodeConverter,
  238.                    &target,
  239.                    targetLimit,
  240.                    &source,
  241.                    sourceLimit,
  242.              offsets,
  243.                    flush,
  244.                    &err);
  245. }
  246.  
  247.  
  248.  
  249. void
  250. UnicodeConverterCPP::toUnicode(UChar*&           target,
  251.                    const UChar*      targetLimit,
  252.                    const char*&        source,
  253.                    const char*         sourceLimit,
  254.                    int32_t* offsets,
  255.                    bool_t              flush,
  256.                    UErrorCode&          err)
  257. {
  258.     ucnv_toUnicode(myUnicodeConverter,
  259.                  &target,
  260.                  targetLimit,
  261.                  &source,
  262.                  sourceLimit,
  263.            offsets,
  264.                  flush,
  265.                  &err);
  266. }
  267.  
  268. const char*
  269. UnicodeConverterCPP::getName(UErrorCode&  err) const
  270. {
  271.   return ucnv_getName(myUnicodeConverter, &err);
  272. }
  273.  
  274.  int8_t
  275. UnicodeConverterCPP::getMaxBytesPerChar() const
  276. {
  277.     return ucnv_getMaxCharSize(myUnicodeConverter);
  278. }
  279.  
  280. int8_t
  281. UnicodeConverterCPP::getMinBytesPerChar() const
  282. {
  283.     return ucnv_getMinCharSize(myUnicodeConverter);
  284. }
  285.  
  286. void
  287. UnicodeConverterCPP::getSubstitutionChars(char*             subChars,
  288.                                           int8_t&           len,
  289.                                           UErrorCode&        err) const
  290. {
  291.     ucnv_getSubstChars(myUnicodeConverter,
  292.                         subChars,
  293.                         &len,
  294.                         &err);
  295. }
  296.  
  297. void
  298. UnicodeConverterCPP::setSubstitutionChars(const char*       subChars,
  299.                                           int8_t            len,
  300.                                           UErrorCode&        err)
  301. {
  302.     ucnv_setSubstChars(myUnicodeConverter,
  303.                         subChars,
  304.                         len,
  305.                         &err);
  306. }
  307.  
  308.  
  309. void
  310. UnicodeConverterCPP::resetState()
  311. {
  312.     ucnv_reset(myUnicodeConverter);
  313. }
  314.  
  315.  
  316. int32_t
  317. UnicodeConverterCPP::getCodepage(UErrorCode& err) const
  318. {
  319.     return ucnv_getCCSID(myUnicodeConverter, &err);
  320. }
  321.  
  322. UConverterToUCallback
  323. UnicodeConverterCPP::getMissingCharAction() const
  324. {
  325.     return ucnv_getToUCallBack(myUnicodeConverter);
  326. }
  327.  
  328. UConverterFromUCallback
  329. UnicodeConverterCPP::getMissingUnicodeAction() const
  330. {
  331.     return ucnv_getFromUCallBack(myUnicodeConverter);
  332. }
  333.  
  334.  
  335. void
  336. UnicodeConverterCPP::setMissingCharAction(UConverterToUCallback  action,
  337.                                           UErrorCode&         err)
  338. {
  339.     ucnv_setToUCallBack(myUnicodeConverter, action, &err);
  340. }
  341.  
  342. void
  343. UnicodeConverterCPP::setMissingUnicodeAction(UConverterFromUCallback   action,
  344.                                              UErrorCode&             err)
  345. {
  346.     ucnv_setFromUCallBack(myUnicodeConverter, action, &err);
  347. }
  348.  
  349.  
  350. void
  351. UnicodeConverterCPP::getDisplayName(const Locale&   displayLocale,
  352.                                     UnicodeString&  displayName) const
  353. {
  354.  
  355.   UErrorCode err = U_ZERO_ERROR;
  356.   ResourceBundle rb("", displayLocale, err);
  357.   char tablename[UCNV_MAX_CONVERTER_NAME_LENGTH];
  358.  
  359.   if (U_SUCCESS(err))
  360.     {
  361.       rb.getString(UnicodeString(tablename), displayName, err);
  362.     }
  363.  
  364.   if (U_FAILURE(err))
  365.     {
  366.       /*Error While creating the resource bundle use the internal name instead*/
  367.       displayName.remove();
  368.       displayName = getName(err); /*Get the raw ASCII name*/
  369.  
  370.     }
  371.  
  372.   return;
  373.  
  374. }
  375.  
  376.  
  377. UConverterPlatform
  378. UnicodeConverterCPP::getCodepagePlatform(UErrorCode &err) const
  379. {
  380.     return ucnv_getPlatform(myUnicodeConverter, &err);
  381. }
  382.  
  383. UConverterType UnicodeConverterCPP::getType() const
  384. {
  385.   return ucnv_getType(myUnicodeConverter);
  386. }
  387.  
  388. void UnicodeConverterCPP::getStarters(bool_t starters[256],
  389.                  UErrorCode& err) const
  390. {
  391.   ucnv_getStarters(myUnicodeConverter,
  392.            starters,
  393.            &err);
  394.   return;
  395. }
  396.  
  397. const char* const*
  398. UnicodeConverterCPP::getAvailableNames(int32_t& num, UErrorCode& err)
  399. {
  400.   num = ucnv_countAvailable();
  401.   return AVAILABLE_CONVERTERS_NAMES;
  402.  
  403. }
  404.  
  405. int32_t  UnicodeConverterCPP::flushCache()
  406. {
  407.   return ucnv_flushCache();
  408. }
  409.