unicode.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:11k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: unicode.cpp,v $
  4.  * PRODUCTION Revision 1000.0  2004/06/01 19:43:29  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.3
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: unicode.cpp,v 1000.0 2004/06/01 19:43:29 gouriano Exp $
  10.  * ==========================================================================
  11.  *
  12.  *                            PUBLIC DOMAIN NOTICE
  13.  *               National Center for Biotechnology Information
  14.  *
  15.  *  This software/database is a "United States Government Work" under the
  16.  *  terms of the United States Copyright Act.  It was written as part of
  17.  *  the author's official duties as a United States Government employee and
  18.  *  thus cannot be copyrighted.  This software/database is freely available
  19.  *  to the public for use. The National Library of Medicine and the U.S.
  20.  *  Government have not placed any restriction on its use or reproduction.
  21.  *
  22.  *  Although all reasonable efforts have been taken to ensure the accuracy
  23.  *  and reliability of the software and data, the NLM and the U.S.
  24.  *  Government do not and cannot warrant the performance or results that
  25.  *  may be obtained by using this software or data. The NLM and the U.S.
  26.  *  Government disclaim all warranties, express or implied, including
  27.  *  warranties of performance, merchantability or fitness for any particular
  28.  *  purpose.
  29.  *
  30.  *  Please cite the author in any work or product based on this material.
  31.  *
  32.  * ==========================================================================
  33.  *
  34.  * Author: Aleksey Vinokurov
  35.  *
  36.  * File Description:
  37.  *    Unicode transformation library
  38.  *
  39.  */
  40. #include <ncbi_pch.hpp>
  41. #include <util/unicode.hpp>
  42. BEGIN_NCBI_SCOPE
  43. BEGIN_SCOPE(utf8)
  44. #include "unicode_plans/plan00.inc"
  45. #include "unicode_plans/plan01.inc"
  46. #include "unicode_plans/plan02.inc"
  47. #include "unicode_plans/plan03.inc"
  48. #include "unicode_plans/plan04.inc"
  49. #include "unicode_plans/plan1e.inc"
  50. #include "unicode_plans/plan20.inc"
  51. #include "unicode_plans/plan21.inc"
  52. #include "unicode_plans/plan22.inc"
  53. #include "unicode_plans/plan23.inc"
  54. #include "unicode_plans/plan24.inc"
  55. #include "unicode_plans/plan25.inc"
  56. #include "unicode_plans/plan26.inc"
  57. #include "unicode_plans/plan27.inc"
  58. #include "unicode_plans/plan30.inc"
  59. #include "unicode_plans/plane0.inc"
  60. #include "unicode_plans/plane2.inc"
  61. #include "unicode_plans/plane3.inc"
  62. #include "unicode_plans/plane4.inc"
  63. #include "unicode_plans/plane5.inc"
  64. #include "unicode_plans/plane6.inc"
  65. #include "unicode_plans/plane7.inc"
  66. #include "unicode_plans/plane8.inc"
  67. #include "unicode_plans/planea.inc"
  68. #include "unicode_plans/planeb.inc"
  69. #include "unicode_plans/planfb.inc"
  70. #include "unicode_plans/planfe.inc"
  71. static TUnicodeTable g_DefaultUnicodeTable =
  72. {
  73.     &s_Plan_00h, &s_Plan_01h, &s_Plan_02h, &s_Plan_03h, &s_Plan_04h, 0, 0, 0,  // Plan 00 - 07
  74.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 08 - 0F
  75.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 10 - 17
  76.     0, 0, 0, 0, 0, 0, &s_Plan_1Eh, 0,  // Plan 18 - 1F
  77.     &s_Plan_20h, &s_Plan_21h, &s_Plan_22h, &s_Plan_23h, &s_Plan_24h, &s_Plan_25h, &s_Plan_26h, &s_Plan_27h,  // Plan 20 - 27
  78.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 28 - 2F
  79.     &s_Plan_30h, 0, 0, 0, 0, 0, 0, 0,  // Plan 30 - 37
  80.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 38 - 3F
  81.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 40 - 47
  82.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 48 - 4F
  83.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 50 - 57
  84.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 58 - 5F
  85.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 60 - 67
  86.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 68 - 6F
  87.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 70 - 77
  88.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 78 - 7F
  89.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 80 - 87
  90.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 88 - 8F
  91.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 90 - 97
  92.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan 98 - 9F
  93.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan A0 - A7
  94.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan A8 - AF
  95.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan B0 - B7
  96.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan B8 - BF
  97.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan C0 - C7
  98.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan C8 - CF
  99.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan D0 - D7
  100.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan D8 - DF
  101.     &s_Plan_E0h, 0, &s_Plan_E2h, &s_Plan_E3h, &s_Plan_E4h, &s_Plan_E5h, &s_Plan_E6h, &s_Plan_E7h,  // Plan E0 - E7
  102.     &s_Plan_E8h, 0, &s_Plan_EAh, &s_Plan_EBh, 0, 0, 0, 0,  // Plan E8 - EF
  103.     0, 0, 0, 0, 0, 0, 0, 0,  // Plan F0 - F7
  104.     0, 0, 0, &s_Plan_FBh, 0, 0, &s_Plan_FEh, 0   // Plan F8 - FF
  105. };
  106. const SUnicodeTranslation*
  107. UnicodeToAscii(TUnicode character, const TUnicodeTable* table)
  108. {
  109.     if (!table) {
  110.         table = &g_DefaultUnicodeTable;
  111.     }
  112.     unsigned int thePlanNo   = (character & 0xFF00) >> 8;
  113.     unsigned int theOffset = character & 0xFF;
  114.     const TUnicodePlan* thePlan = (*table)[thePlanNo];
  115.     if ( !thePlan ) return 0;
  116.     return &((*thePlan)[theOffset]);
  117. }
  118. TUnicode UTF8ToUnicode( const char* theUTF )
  119. {
  120.     int seq_len;
  121.     const char *p = theUTF;
  122.     char counter = *p++;
  123.     unsigned char c;
  124.     if ( ((*theUTF) & 0xC0) != 0xC0 )
  125.     {
  126.         TUnicode RC = 0;
  127.         RC |= (unsigned char)theUTF[0];
  128.         return RC;
  129.     }
  130.     TUnicode acc = counter & 037;
  131.     while((counter <<= 1) < 0) {
  132.         c = *p++;
  133.         if((c & ~077) != 0200) { // Broken UTF-8 chain
  134.             seq_len = p - theUTF;
  135.             return ~0;
  136.         }
  137.         acc = (acc << 6) | (c & 077);
  138.     }
  139.     return acc;
  140. }
  141. int UTF8ToUnicode( const char* theUTF, TUnicode* theUnicode )
  142. {
  143.     int seq_len;
  144.     const char *p = theUTF;
  145.     char counter = *p++;
  146.     unsigned char c;
  147.     if ( (unsigned char )theUTF[0] < 0x80 ) {
  148.         // This is one character UTF8. I.e. regular character.
  149.         *theUnicode = *theUTF;
  150.         return 1;
  151.     }
  152.     if ( ((*theUTF) & 0xC0) != 0xC0 ) {
  153.         // This is not a unicode
  154.         return 0;
  155.     }
  156.     TUnicode acc = counter & 037;
  157.     while((counter <<= 1) < 0) {
  158.         c = *p++;
  159.         if((c & ~077) != 0200) { // Broken UTF-8 chain
  160.             seq_len = p - theUTF;
  161.             return ~0;
  162.         }
  163.         acc = (acc << 6) | (c & 077);
  164.     } // while
  165.     seq_len = p - theUTF;
  166.     *theUnicode = acc;
  167.     return seq_len;
  168. }
  169. string UnicodeToUTF8( TUnicode theUnicode )
  170. {
  171.     char theBuffer[10];
  172.     int theLength = UnicodeToUTF8( theUnicode, theBuffer, 10 );
  173.     return string( theBuffer, theLength );
  174. }
  175. int UnicodeToUTF8( TUnicode theUnicode, char *theBuffer, int theBufLength )
  176. {
  177.     int Length = 0;
  178.     if (theUnicode < 0x80) {
  179.         Length = 1;
  180.         if ( Length > theBufLength ) return 0;
  181.         theBuffer[0] = char(theUnicode);
  182.     }
  183.     else if (theUnicode < 0x800) {
  184.         Length = 2;
  185.         if ( Length > theBufLength ) return 0;
  186.         theBuffer[0] = char(0xC0 | theUnicode>>6);
  187.         theBuffer[1] = char(0x80 | theUnicode & 0x3F);
  188.     }
  189.     else if (theUnicode < 0x10000) {
  190.         Length = 3;
  191.         if ( Length > theBufLength ) return 0;
  192.         theBuffer[0] = char(0xE0 | theUnicode>>12);
  193.         theBuffer[1] = char(0x80 | theUnicode>>6 & 0x3F);
  194.         theBuffer[2] = char(0x80 | theUnicode & 0x3F);
  195.     }
  196.     else if (theUnicode < 0x200000) {
  197.         Length = 4;
  198.         if ( Length > theBufLength ) return 0;
  199.         theBuffer[0] = char(0xF0 | theUnicode>>18);
  200.         theBuffer[1] = char(0x80 | theUnicode>>12 & 0x3F);
  201.         theBuffer[2] = char(0x80 | theUnicode>>6 & 0x3F);
  202.         theBuffer[3] = char(0x80 | theUnicode & 0x3F);
  203.     }
  204.     return Length;
  205. }
  206. int UTF8ToAscii( const char* src, char* dst,
  207.                  int dstLen, const TUnicodeTable* table)
  208. {
  209.     if ( !src || !dst || dstLen == 0 ) return 0;
  210.     long srcPos = 0;
  211.     long dstPos = 0;
  212.     long srcLen = strlen( src );
  213.     for ( srcPos = 0; srcPos < srcLen; )
  214.     {
  215.         // Assign quck pointers
  216.         char* pDst = &(dst[dstPos]);
  217.         const char* pSrc = &(src[srcPos]);
  218.         TUnicode theUnicode;
  219.         int utfLen = UTF8ToUnicode( pSrc, &theUnicode );
  220.         if ( (utfLen == 0) || (utfLen == -1) ) {
  221.             // Skip the error.
  222.             srcPos++;
  223.             continue;
  224.         }
  225.         srcPos += utfLen;
  226.         // Find the correct substitution.
  227.         const SUnicodeTranslation*
  228.             pSubst = UnicodeToAscii( theUnicode, table );
  229.         // Check if the unicode has a translation
  230.         if ( !pSubst ) {
  231.             continue;
  232.         }
  233.         // Check if type is eSkip or substituting string is empty.
  234.         if ( (pSubst->Type ==  eSkip) ||
  235.              !(pSubst->Subst) ) {
  236.             continue;
  237.         }
  238.         // Check if type is eAsIs
  239.         if (pSubst->Type ==  eAsIs) {
  240.             memcpy( pDst, pSrc, utfLen );
  241.             dstPos += utfLen;
  242.             continue;
  243.         }
  244.         // Check the remaining length and put the result in there.
  245.         int substLen = strlen( pSubst->Subst );
  246.         if ( (dstPos + substLen) > dstLen ) {
  247.             return -1; // Unsufficient space;
  248.         }
  249.         // Copy the substituting value into the destignation string
  250.         memcpy( pDst, pSubst->Subst, substLen );
  251.         dstPos += substLen;
  252.     }
  253.     return dstPos;
  254. }
  255. string UTF8ToAsciiString( const char* src, const TUnicodeTable* table)
  256. {
  257.     if ( !src ) return 0;
  258.     string dst;
  259.     long srcPos = 0;
  260.     long srcLen = strlen( src );
  261.     for ( srcPos = 0; srcPos < srcLen; )
  262.     {
  263.         // Assign quck pointers
  264.         const char* pSrc = &(src[srcPos]);
  265.         TUnicode theUnicode;
  266.         int utfLen = UTF8ToUnicode( pSrc, &theUnicode );
  267.         if ( (utfLen == 0) || (utfLen == -1) ) {
  268.             // Skip the error.
  269.             srcPos++;
  270.             continue;
  271.         }
  272.         srcPos += utfLen;
  273.         // Find the correct substitution.
  274.         const SUnicodeTranslation*
  275.             pSubst = UnicodeToAscii( theUnicode, table );
  276.         // Check if the unicode has a translation
  277.         if ( !pSubst ) {
  278.             srcPos += utfLen;
  279.             continue;
  280.         }
  281.         // Check if type is eSkip or substituting string is empty.
  282.         if ( (pSubst->Type ==  eSkip) ||
  283.              !(pSubst->Subst) ) {
  284.             srcPos += utfLen;
  285.             continue;
  286.         }
  287.         // Check if type is eAsIs
  288.         if (pSubst->Type ==  eAsIs) {
  289.             dst += string( pSrc, utfLen );
  290.             srcPos += utfLen;
  291.             continue;
  292.         }
  293.         // Copy the substituting value into the destignation string
  294.         dst += pSubst->Subst;
  295.     }
  296.     return dst;
  297. }
  298. END_SCOPE(utf8)
  299. END_NCBI_SCOPE
  300. /*
  301.  * ==========================================================================
  302.  * $Log: unicode.cpp,v $
  303.  * Revision 1000.0  2004/06/01 19:43:29  gouriano
  304.  * PRODUCTION: IMPORTED [GCC34_MSVC7] Dev-tree R1.3
  305.  *
  306.  * Revision 1.3  2004/05/17 21:06:02  gorelenk
  307.  * Added include of PCH ncbi_pch.hpp
  308.  *
  309.  * Revision 1.2  2004/05/13 21:18:12  ucko
  310.  * Respect constness in UnicodeToAscii.
  311.  *
  312.  * Revision 1.1  2004/05/06 18:15:29  gouriano
  313.  * Imported from pubmed/xmldb
  314.  *
  315.  * ==========================================================================
  316.  */