gfx/skia/trunk/src/core/SkUtils.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.

     2 /*
     3  * Copyright 2006 The Android Open Source Project
     4  *
     5  * Use of this source code is governed by a BSD-style license that can be
     6  * found in the LICENSE file.
     7  */
    10 #include "SkUtils.h"
    12 #if 0
    13 #define assign_16_longs(dst, value)             \
    14     do {                                        \
    15         (dst)[0] = value;   (dst)[1] = value;   \
    16         (dst)[2] = value;   (dst)[3] = value;   \
    17         (dst)[4] = value;   (dst)[5] = value;   \
    18         (dst)[6] = value;   (dst)[7] = value;   \
    19         (dst)[8] = value;   (dst)[9] = value;   \
    20         (dst)[10] = value;  (dst)[11] = value;  \
    21         (dst)[12] = value;  (dst)[13] = value;  \
    22         (dst)[14] = value;  (dst)[15] = value;  \
    23     } while (0)
    24 #else
    25 #define assign_16_longs(dst, value)             \
    26     do {                                        \
    27         *(dst)++ = value;   *(dst)++ = value;   \
    28         *(dst)++ = value;   *(dst)++ = value;   \
    29         *(dst)++ = value;   *(dst)++ = value;   \
    30         *(dst)++ = value;   *(dst)++ = value;   \
    31         *(dst)++ = value;   *(dst)++ = value;   \
    32         *(dst)++ = value;   *(dst)++ = value;   \
    33         *(dst)++ = value;   *(dst)++ = value;   \
    34         *(dst)++ = value;   *(dst)++ = value;   \
    35     } while (0)
    36 #endif
    38 ///////////////////////////////////////////////////////////////////////////////
    40 void sk_memset16_portable(uint16_t dst[], uint16_t value, int count) {
    41     SkASSERT(dst != NULL && count >= 0);
    43     if (count <= 0) {
    44         return;
    45     }
    47     // not sure if this helps to short-circuit on small values of count
    48     if (count < 8) {
    49         do {
    50             *dst++ = (uint16_t)value;
    51         } while (--count != 0);
    52         return;
    53     }
    55     // ensure we're on a long boundary
    56     if ((size_t)dst & 2) {
    57         *dst++ = (uint16_t)value;
    58         count -= 1;
    59     }
    61     uint32_t value32 = ((uint32_t)value << 16) | value;
    63     // handle the bulk with our unrolled macro
    64     {
    65         int sixteenlongs = count >> 5;
    66         if (sixteenlongs) {
    67             uint32_t* dst32 = (uint32_t*)dst;
    68             do {
    69                 assign_16_longs(dst32, value32);
    70             } while (--sixteenlongs != 0);
    71             dst = (uint16_t*)dst32;
    72             count &= 31;
    73         }
    74     }
    76     // handle (most) of the rest
    77     {
    78         int longs = count >> 1;
    79         if (longs) {
    80             do {
    81                 *(uint32_t*)dst = value32;
    82                 dst += 2;
    83             } while (--longs != 0);
    84         }
    85     }
    87     // cleanup a possible trailing short
    88     if (count & 1) {
    89         *dst = (uint16_t)value;
    90     }
    91 }
    93 void sk_memset32_portable(uint32_t dst[], uint32_t value, int count) {
    94     SkASSERT(dst != NULL && count >= 0);
    96     int sixteenlongs = count >> 4;
    97     if (sixteenlongs) {
    98         do {
    99             assign_16_longs(dst, value);
   100         } while (--sixteenlongs != 0);
   101         count &= 15;
   102     }
   104     if (count) {
   105         do {
   106             *dst++ = value;
   107         } while (--count != 0);
   108     }
   109 }
   111 static void sk_memset16_stub(uint16_t dst[], uint16_t value, int count) {
   112     SkMemset16Proc proc = SkMemset16GetPlatformProc();
   113     sk_memset16 = proc ? proc : sk_memset16_portable;
   114     sk_memset16(dst, value, count);
   115 }
   117 SkMemset16Proc sk_memset16 = sk_memset16_stub;
   119 static void sk_memset32_stub(uint32_t dst[], uint32_t value, int count) {
   120     SkMemset32Proc proc = SkMemset32GetPlatformProc();
   121     sk_memset32 = proc ? proc : sk_memset32_portable;
   122     sk_memset32(dst, value, count);
   123 }
   125 SkMemset32Proc sk_memset32 = sk_memset32_stub;
   127 ///////////////////////////////////////////////////////////////////////////////
   129 /*  0xxxxxxx    1 total
   130     10xxxxxx    // never a leading byte
   131     110xxxxx    2 total
   132     1110xxxx    3 total
   133     11110xxx    4 total
   135     11 10 01 01 xx xx xx xx 0...
   136     0xE5XX0000
   137     0xE5 << 24
   138 */
   140 #ifdef SK_DEBUG
   141     static void assert_utf8_leadingbyte(unsigned c) {
   142         SkASSERT(c <= 0xF7);    // otherwise leading byte is too big (more than 4 bytes)
   143         SkASSERT((c & 0xC0) != 0x80);   // can't begin with a middle char
   144     }
   146     int SkUTF8_LeadByteToCount(unsigned c) {
   147         assert_utf8_leadingbyte(c);
   148         return (((0xE5 << 24) >> (c >> 4 << 1)) & 3) + 1;
   149     }
   150 #else
   151     #define assert_utf8_leadingbyte(c)
   152 #endif
   154 int SkUTF8_CountUnichars(const char utf8[]) {
   155     SkASSERT(utf8);
   157     int count = 0;
   159     for (;;) {
   160         int c = *(const uint8_t*)utf8;
   161         if (c == 0) {
   162             break;
   163         }
   164         utf8 += SkUTF8_LeadByteToCount(c);
   165         count += 1;
   166     }
   167     return count;
   168 }
   170 int SkUTF8_CountUnichars(const char utf8[], size_t byteLength) {
   171     SkASSERT(NULL != utf8 || 0 == byteLength);
   173     int         count = 0;
   174     const char* stop = utf8 + byteLength;
   176     while (utf8 < stop) {
   177         utf8 += SkUTF8_LeadByteToCount(*(const uint8_t*)utf8);
   178         count += 1;
   179     }
   180     return count;
   181 }
   183 SkUnichar SkUTF8_ToUnichar(const char utf8[]) {
   184     SkASSERT(NULL != utf8);
   186     const uint8_t*  p = (const uint8_t*)utf8;
   187     int             c = *p;
   188     int             hic = c << 24;
   190     assert_utf8_leadingbyte(c);
   192     if (hic < 0) {
   193         uint32_t mask = (uint32_t)~0x3F;
   194         hic <<= 1;
   195         do {
   196             c = (c << 6) | (*++p & 0x3F);
   197             mask <<= 5;
   198         } while ((hic <<= 1) < 0);
   199         c &= ~mask;
   200     }
   201     return c;
   202 }
   204 SkUnichar SkUTF8_NextUnichar(const char** ptr) {
   205     SkASSERT(NULL != ptr && NULL != *ptr);
   207     const uint8_t*  p = (const uint8_t*)*ptr;
   208     int             c = *p;
   209     int             hic = c << 24;
   211     assert_utf8_leadingbyte(c);
   213     if (hic < 0) {
   214         uint32_t mask = (uint32_t)~0x3F;
   215         hic <<= 1;
   216         do {
   217             c = (c << 6) | (*++p & 0x3F);
   218             mask <<= 5;
   219         } while ((hic <<= 1) < 0);
   220         c &= ~mask;
   221     }
   222     *ptr = (char*)p + 1;
   223     return c;
   224 }
   226 SkUnichar SkUTF8_PrevUnichar(const char** ptr) {
   227     SkASSERT(NULL != ptr && NULL != *ptr);
   229     const char* p = *ptr;
   231     if (*--p & 0x80) {
   232         while (*--p & 0x40) {
   233             ;
   234         }
   235     }
   237     *ptr = (char*)p;
   238     return SkUTF8_NextUnichar(&p);
   239 }
   241 size_t SkUTF8_FromUnichar(SkUnichar uni, char utf8[]) {
   242     if ((uint32_t)uni > 0x10FFFF) {
   243         SkDEBUGFAIL("bad unichar");
   244         return 0;
   245     }
   247     if (uni <= 127) {
   248         if (utf8) {
   249             *utf8 = (char)uni;
   250         }
   251         return 1;
   252     }
   254     char    tmp[4];
   255     char*   p = tmp;
   256     size_t  count = 1;
   258     SkDEBUGCODE(SkUnichar orig = uni;)
   260     while (uni > 0x7F >> count) {
   261         *p++ = (char)(0x80 | (uni & 0x3F));
   262         uni >>= 6;
   263         count += 1;
   264     }
   266     if (utf8) {
   267         p = tmp;
   268         utf8 += count;
   269         while (p < tmp + count - 1) {
   270             *--utf8 = *p++;
   271         }
   272         *--utf8 = (char)(~(0xFF >> count) | uni);
   273     }
   275     SkASSERT(utf8 == NULL || orig == SkUTF8_ToUnichar(utf8));
   276     return count;
   277 }
   279 ///////////////////////////////////////////////////////////////////////////////
   281 int SkUTF16_CountUnichars(const uint16_t src[]) {
   282     SkASSERT(src);
   284     int count = 0;
   285     unsigned c;
   286     while ((c = *src++) != 0) {
   287         SkASSERT(!SkUTF16_IsLowSurrogate(c));
   288         if (SkUTF16_IsHighSurrogate(c)) {
   289             c = *src++;
   290             SkASSERT(SkUTF16_IsLowSurrogate(c));
   291         }
   292         count += 1;
   293     }
   294     return count;
   295 }
   297 int SkUTF16_CountUnichars(const uint16_t src[], int numberOf16BitValues) {
   298     SkASSERT(src);
   300     const uint16_t* stop = src + numberOf16BitValues;
   301     int count = 0;
   302     while (src < stop) {
   303         unsigned c = *src++;
   304         SkASSERT(!SkUTF16_IsLowSurrogate(c));
   305         if (SkUTF16_IsHighSurrogate(c)) {
   306             SkASSERT(src < stop);
   307             c = *src++;
   308             SkASSERT(SkUTF16_IsLowSurrogate(c));
   309         }
   310         count += 1;
   311     }
   312     return count;
   313 }
   315 SkUnichar SkUTF16_NextUnichar(const uint16_t** srcPtr) {
   316     SkASSERT(srcPtr && *srcPtr);
   318     const uint16_t* src = *srcPtr;
   319     SkUnichar       c = *src++;
   321     SkASSERT(!SkUTF16_IsLowSurrogate(c));
   322     if (SkUTF16_IsHighSurrogate(c)) {
   323         unsigned c2 = *src++;
   324         SkASSERT(SkUTF16_IsLowSurrogate(c2));
   326         // c = ((c & 0x3FF) << 10) + (c2 & 0x3FF) + 0x10000
   327         // c = (((c & 0x3FF) + 64) << 10) + (c2 & 0x3FF)
   328         c = (c << 10) + c2 + (0x10000 - (0xD800 << 10) - 0xDC00);
   329     }
   330     *srcPtr = src;
   331     return c;
   332 }
   334 SkUnichar SkUTF16_PrevUnichar(const uint16_t** srcPtr) {
   335     SkASSERT(srcPtr && *srcPtr);
   337     const uint16_t* src = *srcPtr;
   338     SkUnichar       c = *--src;
   340     SkASSERT(!SkUTF16_IsHighSurrogate(c));
   341     if (SkUTF16_IsLowSurrogate(c)) {
   342         unsigned c2 = *--src;
   343         SkASSERT(SkUTF16_IsHighSurrogate(c2));
   344         c = (c2 << 10) + c + (0x10000 - (0xD800 << 10) - 0xDC00);
   345     }
   346     *srcPtr = src;
   347     return c;
   348 }
   350 size_t SkUTF16_FromUnichar(SkUnichar uni, uint16_t dst[]) {
   351     SkASSERT((unsigned)uni <= 0x10FFFF);
   353     int extra = (uni > 0xFFFF);
   355     if (dst) {
   356         if (extra) {
   357             // dst[0] = SkToU16(0xD800 | ((uni - 0x10000) >> 10));
   358             // dst[0] = SkToU16(0xD800 | ((uni >> 10) - 64));
   359             dst[0] = SkToU16((0xD800 - 64) + (uni >> 10));
   360             dst[1] = SkToU16(0xDC00 | (uni & 0x3FF));
   362             SkASSERT(SkUTF16_IsHighSurrogate(dst[0]));
   363             SkASSERT(SkUTF16_IsLowSurrogate(dst[1]));
   364         } else {
   365             dst[0] = SkToU16(uni);
   366             SkASSERT(!SkUTF16_IsHighSurrogate(dst[0]));
   367             SkASSERT(!SkUTF16_IsLowSurrogate(dst[0]));
   368         }
   369     }
   370     return 1 + extra;
   371 }
   373 size_t SkUTF16_ToUTF8(const uint16_t utf16[], int numberOf16BitValues,
   374                       char utf8[]) {
   375     SkASSERT(numberOf16BitValues >= 0);
   376     if (numberOf16BitValues <= 0) {
   377         return 0;
   378     }
   380     SkASSERT(utf16 != NULL);
   382     const uint16_t* stop = utf16 + numberOf16BitValues;
   383     size_t          size = 0;
   385     if (utf8 == NULL) {    // just count
   386         while (utf16 < stop) {
   387             size += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&utf16), NULL);
   388         }
   389     } else {
   390         char* start = utf8;
   391         while (utf16 < stop) {
   392             utf8 += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&utf16), utf8);
   393         }
   394         size = utf8 - start;
   395     }
   396     return size;
   397 }

mercurial