Ignore:
Timestamp:
Nov 17, 2006, 10:42:35 PM (15 years ago)
Author:
Eugene Romanenko
Message:

optimized unicode conversion, fixes crash in uconv.dll (closes #97)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Lucide/SOURCE/gui/clipbrd.cpp

    r37 r156  
    2222 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
    2323 * in which case the provisions of the LGPL are applicable instead of those
    24  * above. If you wish to allow use of your version of this file only under the 
     24 * above. If you wish to allow use of your version of this file only under the
    2525 * terms of the LGPL, and not to allow others to use your version of this file
    2626 * under the terms of the CDDL, indicate your decision by deleting the
    2727 * provisions above and replace them with the notice and other provisions
    2828 * required by the LGPL. If you do not delete the provisions above, a recipient
    29  * may use your version of this file under the terms of any one of the CDDL 
     29 * may use your version of this file under the terms of any one of the CDDL
    3030 * or the LGPL.
    3131 *
     
    3636#define INCL_DOS
    3737#include <os2.h>
     38
     39#include <uconv.h>
     40#include <unidef.h>
    3841
    3942#include <string.h>
     
    5962}
    6063
     64
    6165void textToClipbrd( HAB hab, const char *text )
    6266{
     67    void *objtouni, *objtosys;
     68    int rc = ULS_SUCCESS;
     69    rc = UniCreateUconvObject( (UniChar *)L"UTF-8", &objtouni );
     70    if ( rc != ULS_SUCCESS ) {
     71        return;
     72    }
     73    rc = UniCreateUconvObject( (UniChar *)L"", &objtosys );
     74    if ( rc != ULS_SUCCESS ) {
     75        UniFreeUconvObject( objtouni );
     76        return;
     77    }
     78
     79    uconv_attribute_t attr;
     80    UniQueryUconvObject( objtouni, &attr, sizeof(attr), NULL, NULL, NULL );
     81    attr.converttype &= ~(CVTTYPE_CTRL7F | CVTTYPE_PATH);
     82    UniSetUconvObject( objtouni, &attr );
     83    UniQueryUconvObject( objtosys, &attr, sizeof(attr), NULL, NULL, NULL );
     84    attr.options = UCONV_OPTION_SUBSTITUTE_BOTH;
     85    UniSetUconvObject( objtosys, &attr );
     86
    6387    size_t len = 0;
    6488    size_t olen = 0;
    65     const char *tsav = text;
    6689
    6790    if ( WinOpenClipbrd( hab ) )
     
    6992        WinEmptyClipbrd( hab );
    7093
     94        size_t cSubs = 0;
    7195        len = strlen( text );
    72         olen = (len + 2)*2;
    73 
    74         void *memuni = NULL;
     96        olen = ( len + 2 ) * 2;
     97        void *shmemuni = NULL;
     98        void *shmemsys = NULL;
    7599
    76100        // place to clipboard as unicode
    77         if ( DosAllocSharedMem( &memuni, NULL, olen, fALLOCSHR ) == 0 )
     101        if ( DosAllocSharedMem( &shmemuni, NULL, olen, fALLOCSHR ) == 0 )
    78102        {
    79             memset( memuni, 0, olen );
    80             void *tmem = memuni;
    81 
    82             tsav = text;
    83             cnvUTF8ToUni( &text, &len, (char **)&memuni, &olen );
    84             text = tsav;
     103            memset( shmemuni, 0, olen );
     104            size_t unilen = olen / sizeof( UniChar );
     105            UniChar *tmpuni = (UniChar *)shmemuni;
     106            UniUconvToUcs( objtouni, (void **)&text, &len, &tmpuni, &unilen, &cSubs );
     107            unilen = UniStrlen( (UniChar *)shmemuni );
     108            void *memuni = (void *)new char[ olen ];
     109            memcpy( memuni, shmemuni, olen );
    85110
    86111            ULONG ulFormatID = RegisterClipboardFormat( kUnicodeMime );
    87             WinSetClipbrdData( hab, (ULONG)tmem, ulFormatID, CFI_POINTER );
     112            WinSetClipbrdData( hab, (ULONG)shmemuni, ulFormatID, CFI_POINTER );
     113
     114            int liglen = uniLigaturesLength( (UniChar *)memuni );
     115            if ( liglen > 0 )  // string contain ligature(s)
     116            {
     117                unsigned ulen_tmp = ( unilen + liglen + 1 ) * sizeof( UniChar );
     118                char *uni_tmp = new char[ ulen_tmp ];
     119                uniReplaceLigatures( (UniChar *)memuni, (UniChar *)uni_tmp );
     120                delete memuni;
     121                memuni = uni_tmp;
     122                unilen = UniStrlen( (UniChar *)memuni );
     123            }
     124            uniConvertSpChars( (UniChar *)memuni );
     125
     126            // place to clipboard as current codepage
     127            if ( DosAllocSharedMem( &shmemsys, NULL, olen, fALLOCSHR ) == 0 )
     128            {
     129                memset( shmemsys, 0, olen );
     130
     131                cSubs = 0;
     132                tmpuni = (UniChar *)memuni;
     133                void *tmpsys = shmemsys;
     134                UniUconvFromUcs( objtosys, &tmpuni, &unilen, &tmpsys, &olen, &cSubs );
     135
     136                WinSetClipbrdData( hab, (ULONG)shmemsys, CF_TEXT, CFI_POINTER );
     137            }
     138            delete memuni;
    88139        }
    89 
    90         len = strlen( text );
    91         olen = (len + 2)*2;
    92         void *memcp = NULL;
    93 
    94         // place to clipboard as current codepage
    95         if ( DosAllocSharedMem( &memcp, NULL, olen, fALLOCSHR ) == 0 )
    96         {
    97             memset( memcp, 0, olen );
    98             void *tmem = memcp;
    99 
    100             tsav = text;
    101             cnvUTF8ToSys( &text, &len, (char **)&memcp, &olen );
    102                         text = tsav;
    103 
    104             WinSetClipbrdData( hab, (ULONG)tmem, CF_TEXT, CFI_POINTER );
    105         }
    106 
    107140
    108141        WinCloseClipbrd( hab );
    109142    }
     143
     144    UniFreeUconvObject( objtouni );
     145    UniFreeUconvObject( objtosys );
    110146}
    111147
Note: See TracChangeset for help on using the changeset viewer.