intl/icu/source/common/rbbistbl.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 //
     2 //  file:  rbbistbl.cpp    Implementation of the ICU RBBISymbolTable class
     3 //
     4 /*
     5 ***************************************************************************
     6 *   Copyright (C) 2002-2011 International Business Machines Corporation
     7 *   and others. All rights reserved.
     8 ***************************************************************************
     9 */
    11 #include "unicode/utypes.h"
    13 #if !UCONFIG_NO_BREAK_ITERATION
    15 #include "unicode/unistr.h"
    16 #include "unicode/uniset.h"
    17 #include "unicode/uchar.h"
    18 #include "unicode/parsepos.h"
    20 #include "umutex.h"
    22 #include "rbbirb.h"
    23 #include "rbbinode.h"
    26 //
    27 //  RBBISymbolTableEntry_deleter    Used by the UHashTable to delete the contents
    28 //                                  when the hash table is deleted.
    29 //
    30 U_CDECL_BEGIN
    31 static void U_CALLCONV RBBISymbolTableEntry_deleter(void *p) {
    32     icu::RBBISymbolTableEntry *px = (icu::RBBISymbolTableEntry *)p;
    33     delete px;
    34 }
    35 U_CDECL_END
    39 U_NAMESPACE_BEGIN
    41 RBBISymbolTable::RBBISymbolTable(RBBIRuleScanner *rs, const UnicodeString &rules, UErrorCode &status)
    42     :fRules(rules), fRuleScanner(rs), ffffString(UChar(0xffff))
    43 {
    44     fHashTable       = NULL;
    45     fCachedSetLookup = NULL;
    47     fHashTable = uhash_open(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, &status);
    48     // uhash_open checks status
    49     if (U_FAILURE(status)) {
    50         return;
    51     }
    52     uhash_setValueDeleter(fHashTable, RBBISymbolTableEntry_deleter);
    53 }
    57 RBBISymbolTable::~RBBISymbolTable()
    58 {
    59     uhash_close(fHashTable);
    60 }
    63 //
    64 //  RBBISymbolTable::lookup       This function from the abstract symbol table inteface
    65 //                                looks up a variable name and returns a UnicodeString
    66 //                                containing the substitution text.
    67 //
    68 //                                The variable name does NOT include the leading $.
    69 //
    70 const UnicodeString  *RBBISymbolTable::lookup(const UnicodeString& s) const
    71 {
    72     RBBISymbolTableEntry  *el;
    73     RBBINode              *varRefNode;
    74     RBBINode              *exprNode;
    75     RBBINode              *usetNode;
    76     const UnicodeString   *retString;
    77     RBBISymbolTable       *This = (RBBISymbolTable *)this;   // cast off const
    79     el = (RBBISymbolTableEntry *)uhash_get(fHashTable, &s);
    80     if (el == NULL) {
    81         return NULL;
    82     }
    84     varRefNode = el->val;
    85     exprNode   = varRefNode->fLeftChild;     // Root node of expression for variable
    86     if (exprNode->fType == RBBINode::setRef) {
    87         // The $variable refers to a single UnicodeSet
    88         //   return the ffffString, which will subsequently be interpreted as a
    89         //   stand-in character for the set by RBBISymbolTable::lookupMatcher()
    90         usetNode = exprNode->fLeftChild;
    91         This->fCachedSetLookup = usetNode->fInputSet;
    92         retString = &ffffString;
    93     }
    94     else
    95     {
    96         // The variable refers to something other than just a set.
    97         // return the original source string for the expression
    98         retString = &exprNode->fText;
    99         This->fCachedSetLookup = NULL;
   100     }
   101     return retString;
   102 }
   106 //
   107 //  RBBISymbolTable::lookupMatcher   This function from the abstract symbol table
   108 //                                   interface maps a single stand-in character to a
   109 //                                   pointer to a Unicode Set.   The Unicode Set code uses this
   110 //                                   mechanism to get all references to the same $variable
   111 //                                   name to refer to a single common Unicode Set instance.
   112 //
   113 //    This implementation cheats a little, and does not maintain a map of stand-in chars
   114 //    to sets.  Instead, it takes advantage of the fact that  the UnicodeSet
   115 //    constructor will always call this function right after calling lookup(),
   116 //    and we just need to remember what set to return between these two calls.
   117 const UnicodeFunctor *RBBISymbolTable::lookupMatcher(UChar32 ch) const
   118 {
   119     UnicodeSet *retVal = NULL;
   120     RBBISymbolTable *This = (RBBISymbolTable *)this;   // cast off const
   121     if (ch == 0xffff) {
   122         retVal = fCachedSetLookup;
   123         This->fCachedSetLookup = 0;
   124     }
   125     return retVal;
   126 }
   128 //
   129 // RBBISymbolTable::parseReference   This function from the abstract symbol table interface
   130 //                                   looks for a $variable name in the source text.
   131 //                                   It does not look it up, only scans for it.
   132 //                                   It is used by the UnicodeSet parser.
   133 //
   134 //                                   This implementation is lifted pretty much verbatim
   135 //                                   from the rules based transliterator implementation.
   136 //                                   I didn't see an obvious way of sharing it.
   137 //
   138 UnicodeString   RBBISymbolTable::parseReference(const UnicodeString& text,
   139                                                 ParsePosition& pos, int32_t limit) const
   140 {
   141     int32_t start = pos.getIndex();
   142     int32_t i = start;
   143     UnicodeString result;
   144     while (i < limit) {
   145         UChar c = text.charAt(i);
   146         if ((i==start && !u_isIDStart(c)) || !u_isIDPart(c)) {
   147             break;
   148         }
   149         ++i;
   150     }
   151     if (i == start) { // No valid name chars
   152         return result; // Indicate failure with empty string
   153     }
   154     pos.setIndex(i);
   155     text.extractBetween(start, i, result);
   156     return result;
   157 }
   161 //
   162 // RBBISymbolTable::lookupNode      Given a key (a variable name), return the
   163 //                                  corresponding RBBI Node.  If there is no entry
   164 //                                  in the table for this name, return NULL.
   165 //
   166 RBBINode       *RBBISymbolTable::lookupNode(const UnicodeString &key) const{
   168     RBBINode             *retNode = NULL;
   169     RBBISymbolTableEntry *el;
   171     el = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key);
   172     if (el != NULL) {
   173         retNode = el->val;
   174     }
   175     return retNode;
   176 }
   179 //
   180 //    RBBISymbolTable::addEntry     Add a new entry to the symbol table.
   181 //                                  Indicate an error if the name already exists -
   182 //                                    this will only occur in the case of duplicate
   183 //                                    variable assignments.
   184 //
   185 void            RBBISymbolTable::addEntry  (const UnicodeString &key, RBBINode *val, UErrorCode &err) {
   186     RBBISymbolTableEntry *e;
   187     /* test for buffer overflows */
   188     if (U_FAILURE(err)) {
   189         return;
   190     }
   191     e = (RBBISymbolTableEntry *)uhash_get(fHashTable, &key);
   192     if (e != NULL) {
   193         err = U_BRK_VARIABLE_REDFINITION;
   194         return;
   195     }
   197     e = new RBBISymbolTableEntry;
   198     if (e == NULL) {
   199         err = U_MEMORY_ALLOCATION_ERROR;
   200         return;
   201     }
   202     e->key = key;
   203     e->val = val;
   204     uhash_put( fHashTable, &e->key, e, &err);
   205 }
   208 RBBISymbolTableEntry::RBBISymbolTableEntry() : UMemory(), key(), val(NULL) {}
   210 RBBISymbolTableEntry::~RBBISymbolTableEntry() {
   211     // The "val" of a symbol table entry is a variable reference node.
   212     // The l. child of the val is the rhs expression from the assignment.
   213     // Unlike other node types, children of variable reference nodes are not
   214     //    automatically recursively deleted.  We do it manually here.
   215     delete val->fLeftChild;
   216     val->fLeftChild = NULL;
   218     delete  val;
   220     // Note: the key UnicodeString is destructed by virtue of being in the object by value.
   221 }
   224 //
   225 //  RBBISymbolTable::print    Debugging function, dump out the symbol table contents.
   226 //
   227 #ifdef RBBI_DEBUG
   228 void RBBISymbolTable::rbbiSymtablePrint() const {
   229     RBBIDebugPrintf("Variable Definitions\n"
   230            "Name               Node Val     String Val\n"
   231            "----------------------------------------------------------------------\n");
   233     int32_t pos = -1;
   234     const UHashElement  *e   = NULL;
   235     for (;;) {
   236         e = uhash_nextElement(fHashTable,  &pos);
   237         if (e == NULL ) {
   238             break;
   239         }
   240         RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
   242         RBBI_DEBUG_printUnicodeString(s->key, 15);
   243         RBBIDebugPrintf("   %8p   ", (void *)s->val);
   244         RBBI_DEBUG_printUnicodeString(s->val->fLeftChild->fText);
   245         RBBIDebugPrintf("\n");
   246     }
   248     RBBIDebugPrintf("\nParsed Variable Definitions\n");
   249     pos = -1;
   250     for (;;) {
   251         e = uhash_nextElement(fHashTable,  &pos);
   252         if (e == NULL ) {
   253             break;
   254         }
   255         RBBISymbolTableEntry  *s   = (RBBISymbolTableEntry *)e->value.pointer;
   256         RBBI_DEBUG_printUnicodeString(s->key);
   257         s->val->fLeftChild->printTree(TRUE);
   258         RBBIDebugPrintf("\n");
   259     }
   260 }
   261 #endif
   267 U_NAMESPACE_END
   269 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */

mercurial