intl/icu/source/i18n/casetrn.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2 *******************************************************************************
     3 *
     4 *   Copyright (C) 2001-2011, International Business Machines
     5 *   Corporation and others.  All Rights Reserved.
     6 *
     7 *******************************************************************************
     8 *   file name:  casetrn.cpp
     9 *   encoding:   US-ASCII
    10 *   tab size:   8 (not used)
    11 *   indentation:4
    12 *
    13 *   created on: 2004sep03
    14 *   created by: Markus W. Scherer
    15 *
    16 *   Implementation class for lower-/upper-/title-casing transliterators.
    17 */
    19 #include "unicode/utypes.h"
    21 #if !UCONFIG_NO_TRANSLITERATION
    23 #include "unicode/uchar.h"
    24 #include "unicode/ustring.h"
    25 #include "unicode/utf.h"
    26 #include "unicode/utf16.h"
    27 #include "tolowtrn.h"
    28 #include "ucase.h"
    29 #include "cpputils.h"
    31 /* case context iterator using a Replaceable */
    32 U_CFUNC UChar32 U_CALLCONV
    33 utrans_rep_caseContextIterator(void *context, int8_t dir)
    34 {
    35     U_NAMESPACE_USE
    37     UCaseContext *csc=(UCaseContext *)context;
    38     Replaceable *rep=(Replaceable *)csc->p;
    39     UChar32 c;
    41     if(dir<0) {
    42         /* reset for backward iteration */
    43         csc->index=csc->cpStart;
    44         csc->dir=dir;
    45     } else if(dir>0) {
    46         /* reset for forward iteration */
    47         csc->index=csc->cpLimit;
    48         csc->dir=dir;
    49     } else {
    50         /* continue current iteration direction */
    51         dir=csc->dir;
    52     }
    54     // automatically adjust start and limit if the Replaceable disagrees
    55     // with the original values
    56     if(dir<0) {
    57         if(csc->start<csc->index) {
    58             c=rep->char32At(csc->index-1);
    59             if(c<0) {
    60                 csc->start=csc->index;
    61             } else {
    62                 csc->index-=U16_LENGTH(c);
    63                 return c;
    64             }
    65         }
    66     } else {
    67         // detect, and store in csc->b1, if we hit the limit
    68         if(csc->index<csc->limit) {
    69             c=rep->char32At(csc->index);
    70             if(c<0) {
    71                 csc->limit=csc->index;
    72                 csc->b1=TRUE;
    73             } else {
    74                 csc->index+=U16_LENGTH(c);
    75                 return c;
    76             }
    77         } else {
    78             csc->b1=TRUE;
    79         }
    80     }
    81     return U_SENTINEL;
    82 }
    84 U_NAMESPACE_BEGIN
    86 UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(CaseMapTransliterator)
    88 /**
    89  * Constructs a transliterator.
    90  */
    91 CaseMapTransliterator::CaseMapTransliterator(const UnicodeString &id, UCaseMapFull *map) : 
    92     Transliterator(id, 0),
    93     fCsp(ucase_getSingleton()),
    94     fMap(map)
    95 {
    96     // TODO test incremental mode with context-sensitive text (e.g. greek sigma)
    97     // TODO need to call setMaximumContextLength()?!
    98 }
   100 /**
   101  * Destructor.
   102  */
   103 CaseMapTransliterator::~CaseMapTransliterator() {
   104 }
   106 /**
   107  * Copy constructor.
   108  */
   109 CaseMapTransliterator::CaseMapTransliterator(const CaseMapTransliterator& o) :
   110     Transliterator(o),
   111     fCsp(o.fCsp), fMap(o.fMap)
   112 {
   113 }
   115 /**
   116  * Assignment operator.
   117  */
   118 /*CaseMapTransliterator& CaseMapTransliterator::operator=(const CaseMapTransliterator& o) {
   119     Transliterator::operator=(o);
   120     fCsp = o.fCsp;
   121     fMap = o.fMap;
   122     return *this;
   123 }*/
   125 /**
   126  * Transliterator API.
   127  */
   128 /*Transliterator* CaseMapTransliterator::clone(void) const {
   129     return new CaseMapTransliterator(*this);
   130 }*/
   132 /**
   133  * Implements {@link Transliterator#handleTransliterate}.
   134  */
   135 void CaseMapTransliterator::handleTransliterate(Replaceable& text,
   136                                  UTransPosition& offsets, 
   137                                  UBool isIncremental) const
   138 {
   139     if (offsets.start >= offsets.limit) {
   140         return;
   141     }
   143     UCaseContext csc;
   144     uprv_memset(&csc, 0, sizeof(csc));
   145     csc.p = &text;
   146     csc.start = offsets.contextStart;
   147     csc.limit = offsets.contextLimit;
   149     UnicodeString tmp;
   150     const UChar *s;
   151     UChar32 c;
   152     int32_t textPos, delta, result, locCache=0;
   154     for(textPos=offsets.start; textPos<offsets.limit;) {
   155         csc.cpStart=textPos;
   156         c=text.char32At(textPos);
   157         csc.cpLimit=textPos+=U16_LENGTH(c);
   159         result=fMap(fCsp, c, utrans_rep_caseContextIterator, &csc, &s, "", &locCache);
   161         if(csc.b1 && isIncremental) {
   162             // fMap() tried to look beyond the context limit
   163             // wait for more input
   164             offsets.start=csc.cpStart;
   165             return;
   166         }
   168         if(result>=0) {
   169             // replace the current code point with its full case mapping result
   170             // see UCASE_MAX_STRING_LENGTH
   171             if(result<=UCASE_MAX_STRING_LENGTH) {
   172                 // string s[result]
   173                 tmp.setTo(FALSE, s, result);
   174                 delta=result-U16_LENGTH(c);
   175             } else {
   176                 // single code point
   177                 tmp.setTo(result);
   178                 delta=tmp.length()-U16_LENGTH(c);
   179             }
   180             text.handleReplaceBetween(csc.cpStart, textPos, tmp);
   181             if(delta!=0) {
   182                 textPos+=delta;
   183                 csc.limit=offsets.contextLimit+=delta;
   184                 offsets.limit+=delta;
   185             }
   186         }
   187     }
   188     offsets.start=textPos;
   189 }
   191 U_NAMESPACE_END
   193 #endif /* #if !UCONFIG_NO_TRANSLITERATION */

mercurial