LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkString.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 331 0 0.0 %
Date: 2012-06-02 Functions: 42 0 0.0 %

       1                 : 
       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                 :  */
       8                 : 
       9                 : 
      10                 : #include "SkString.h"
      11                 : #include "SkFixed.h"
      12                 : #include "SkThread.h"
      13                 : #include "SkUtils.h"
      14                 : #include <stdarg.h>
      15                 : #include <stdio.h>
      16                 : 
      17                 : // number of bytes (on the stack) to receive the printf result
      18                 : static const size_t kBufferSize = 256;
      19                 : 
      20                 : #ifdef SK_BUILD_FOR_WIN
      21                 :     #define VSNPRINTF(buffer, size, format, args) \
      22                 :         _vsnprintf_s(buffer, size, _TRUNCATE, format, args)
      23                 :     #define SNPRINTF    _snprintf
      24                 : #else
      25                 :     #define VSNPRINTF   vsnprintf
      26                 :     #define SNPRINTF    snprintf
      27                 : #endif
      28                 : 
      29                 : #define ARGS_TO_BUFFER(format, buffer, size)        \
      30                 :     do {                                            \
      31                 :         va_list args;                               \
      32                 :         va_start(args, format);                     \
      33                 :         VSNPRINTF(buffer, size, format, args);      \
      34                 :         va_end(args);                               \
      35                 :     } while (0)
      36                 : 
      37                 : ///////////////////////////////////////////////////////////////////////////////
      38                 : 
      39               0 : bool SkStrStartsWith(const char string[], const char prefix[]) {
      40               0 :     SkASSERT(string);
      41               0 :     SkASSERT(prefix);
      42               0 :     return !strncmp(string, prefix, strlen(prefix));
      43                 : }
      44                 : 
      45               0 : bool SkStrEndsWith(const char string[], const char suffix[]) {
      46               0 :     SkASSERT(string);
      47               0 :     SkASSERT(suffix);
      48               0 :     size_t  strLen = strlen(string);
      49               0 :     size_t  suffixLen = strlen(suffix);
      50                 :     return  strLen >= suffixLen &&
      51               0 :             !strncmp(string + strLen - suffixLen, suffix, suffixLen);
      52                 : }
      53                 : 
      54               0 : int SkStrStartsWithOneOf(const char string[], const char prefixes[]) {
      55               0 :     int index = 0;
      56               0 :     do {
      57               0 :         const char* limit = strchr(prefixes, '\0');
      58               0 :         if (!strncmp(string, prefixes, limit - prefixes)) {
      59               0 :             return index;
      60                 :         }
      61               0 :         prefixes = limit + 1;
      62               0 :         index++;
      63               0 :     } while (prefixes[0]);
      64               0 :     return -1;
      65                 : }
      66                 : 
      67               0 : char* SkStrAppendS32(char string[], int32_t dec) {
      68               0 :     SkDEBUGCODE(char* start = string;)
      69                 : 
      70                 :     char    buffer[SkStrAppendS32_MaxSize];
      71               0 :     char*   p = buffer + sizeof(buffer);
      72               0 :     bool    neg = false;
      73                 : 
      74               0 :     if (dec < 0) {
      75               0 :         neg = true;
      76               0 :         dec = -dec;
      77                 :     }
      78                 : 
      79               0 :     do {
      80               0 :         *--p = SkToU8('0' + dec % 10);
      81               0 :         dec /= 10;
      82                 :     } while (dec != 0);
      83                 : 
      84               0 :     if (neg) {
      85               0 :         *--p = '-';
      86                 :     }
      87                 : 
      88               0 :     SkASSERT(p >= buffer);
      89               0 :     char* stop = buffer + sizeof(buffer);
      90               0 :     while (p < stop) {
      91               0 :         *string++ = *p++;
      92                 :     }
      93               0 :     SkASSERT(string - start <= SkStrAppendS32_MaxSize);
      94               0 :     return string;
      95                 : }
      96                 : 
      97               0 : char* SkStrAppendS64(char string[], int64_t dec, int minDigits) {
      98               0 :     SkDEBUGCODE(char* start = string;)
      99                 : 
     100                 :     char    buffer[SkStrAppendS64_MaxSize];
     101               0 :     char*   p = buffer + sizeof(buffer);
     102               0 :     bool    neg = false;
     103                 : 
     104               0 :     if (dec < 0) {
     105               0 :         neg = true;
     106               0 :         dec = -dec;
     107                 :     }
     108                 : 
     109               0 :     do {
     110               0 :         *--p = SkToU8('0' + dec % 10);
     111               0 :         dec /= 10;
     112               0 :         minDigits--;
     113                 :     } while (dec != 0);
     114                 : 
     115               0 :     while (minDigits > 0) {
     116               0 :         *--p = '0';
     117               0 :         minDigits--;
     118                 :     }
     119                 : 
     120               0 :     if (neg) {
     121               0 :         *--p = '-';
     122                 :     }
     123               0 :     SkASSERT(p >= buffer);
     124               0 :     size_t cp_len = buffer + sizeof(buffer) - p;
     125               0 :     memcpy(string, p, cp_len);
     126               0 :     string += cp_len;
     127                 : 
     128               0 :     SkASSERT(string - start <= SkStrAppendS64_MaxSize);
     129               0 :     return string;
     130                 : }
     131                 : 
     132                 : #ifdef SK_CAN_USE_FLOAT
     133               0 : char* SkStrAppendFloat(char string[], float value) {
     134                 :     // since floats have at most 8 significant digits, we limit our %g to that.
     135                 :     static const char gFormat[] = "%.8g";
     136                 :     // make it 1 larger for the terminating 0
     137                 :     char buffer[SkStrAppendScalar_MaxSize + 1];
     138               0 :     int len = SNPRINTF(buffer, sizeof(buffer), gFormat, value);
     139               0 :     memcpy(string, buffer, len);
     140               0 :     SkASSERT(len <= SkStrAppendScalar_MaxSize);
     141               0 :     return string + len;
     142                 : }
     143                 : #endif
     144                 : 
     145               0 : char* SkStrAppendFixed(char string[], SkFixed x) {
     146               0 :     SkDEBUGCODE(char* start = string;)
     147               0 :     if (x < 0) {
     148               0 :         *string++ = '-';
     149               0 :         x = -x;
     150                 :     }
     151                 : 
     152               0 :     unsigned frac = x & 0xFFFF;
     153               0 :     x >>= 16;
     154               0 :     if (frac == 0xFFFF) {
     155                 :         // need to do this to "round up", since 65535/65536 is closer to 1 than to .9999
     156               0 :         x += 1;
     157               0 :         frac = 0;
     158                 :     }
     159               0 :     string = SkStrAppendS32(string, x);
     160                 : 
     161                 :     // now handle the fractional part (if any)
     162               0 :     if (frac) {
     163                 :         static const uint16_t   gTens[] = { 1000, 100, 10, 1 };
     164               0 :         const uint16_t*         tens = gTens;
     165                 : 
     166               0 :         x = SkFixedRound(frac * 10000);
     167               0 :         SkASSERT(x <= 10000);
     168               0 :         if (x == 10000) {
     169               0 :             x -= 1;
     170                 :         }
     171               0 :         *string++ = '.';
     172               0 :         do {
     173               0 :             unsigned powerOfTen = *tens++;
     174               0 :             *string++ = SkToU8('0' + x / powerOfTen);
     175               0 :             x %= powerOfTen;
     176                 :         } while (x != 0);
     177                 :     }
     178                 : 
     179               0 :     SkASSERT(string - start <= SkStrAppendScalar_MaxSize);
     180               0 :     return string;
     181                 : }
     182                 : 
     183                 : ///////////////////////////////////////////////////////////////////////////////
     184                 : 
     185                 : // the 3 values are [length] [refcnt] [terminating zero data]
     186                 : const SkString::Rec SkString::gEmptyRec = { 0, 0, 0 };
     187                 : 
     188                 : #define SizeOfRec()     (gEmptyRec.data() - (const char*)&gEmptyRec)
     189                 : 
     190               0 : SkString::Rec* SkString::AllocRec(const char text[], size_t len) {
     191                 :     Rec* rec;
     192                 : 
     193               0 :     if (0 == len) {
     194               0 :         rec = const_cast<Rec*>(&gEmptyRec);
     195                 :     } else {
     196                 :         // add 1 for terminating 0, then align4 so we can have some slop when growing the string
     197               0 :         rec = (Rec*)sk_malloc_throw(SizeOfRec() + SkAlign4(len + 1));
     198               0 :         rec->fLength = len;
     199               0 :         rec->fRefCnt = 1;
     200               0 :         if (text) {
     201               0 :             memcpy(rec->data(), text, len);
     202                 :         }
     203               0 :         rec->data()[len] = 0;
     204                 :     }
     205               0 :     return rec;
     206                 : }
     207                 : 
     208               0 : SkString::Rec* SkString::RefRec(Rec* src) {
     209               0 :     if (src != &gEmptyRec) {
     210               0 :         sk_atomic_inc(&src->fRefCnt);
     211                 :     }
     212               0 :     return src;
     213                 : }
     214                 : 
     215                 : #ifdef SK_DEBUG
     216               0 : void SkString::validate() const {
     217                 :     // make sure know one has written over our global
     218               0 :     SkASSERT(0 == gEmptyRec.fLength);
     219               0 :     SkASSERT(0 == gEmptyRec.fRefCnt);
     220               0 :     SkASSERT(0 == gEmptyRec.data()[0]);
     221                 : 
     222               0 :     if (fRec != &gEmptyRec) {
     223               0 :         SkASSERT(fRec->fLength > 0);
     224               0 :         SkASSERT(fRec->fRefCnt > 0);
     225               0 :         SkASSERT(0 == fRec->data()[fRec->fLength]);
     226                 :     }
     227               0 :     SkASSERT(fStr == c_str());
     228               0 : }
     229                 : #endif
     230                 : 
     231                 : ///////////////////////////////////////////////////////////////////////////////
     232                 : 
     233               0 : SkString::SkString() : fRec(const_cast<Rec*>(&gEmptyRec)) {
     234                 : #ifdef SK_DEBUG
     235               0 :     fStr = fRec->data();
     236                 : #endif
     237               0 : }
     238                 : 
     239               0 : SkString::SkString(size_t len) {
     240               0 :     SkASSERT(SkToU16(len) == len);  // can't handle larger than 64K
     241                 : 
     242               0 :     fRec = AllocRec(NULL, (U16CPU)len);
     243                 : #ifdef SK_DEBUG
     244               0 :     fStr = fRec->data();
     245                 : #endif
     246               0 : }
     247                 : 
     248               0 : SkString::SkString(const char text[]) {
     249               0 :     size_t  len = text ? strlen(text) : 0;
     250                 : 
     251               0 :     fRec = AllocRec(text, (U16CPU)len);
     252                 : #ifdef SK_DEBUG
     253               0 :     fStr = fRec->data();
     254                 : #endif
     255               0 : }
     256                 : 
     257               0 : SkString::SkString(const char text[], size_t len) {
     258               0 :     fRec = AllocRec(text, (U16CPU)len);
     259                 : #ifdef SK_DEBUG
     260               0 :     fStr = fRec->data();
     261                 : #endif
     262               0 : }
     263                 : 
     264               0 : SkString::SkString(const SkString& src) {
     265               0 :     src.validate();
     266                 : 
     267               0 :     fRec = RefRec(src.fRec);
     268                 : #ifdef SK_DEBUG
     269               0 :     fStr = fRec->data();
     270                 : #endif
     271               0 : }
     272                 : 
     273               0 : SkString::~SkString() {
     274               0 :     this->validate();
     275                 : 
     276               0 :     if (fRec->fLength) {
     277               0 :         SkASSERT(fRec->fRefCnt > 0);
     278               0 :         if (sk_atomic_dec(&fRec->fRefCnt) == 1) {
     279               0 :             sk_free(fRec);
     280                 :         }
     281                 :     }
     282               0 : }
     283                 : 
     284               0 : bool SkString::equals(const SkString& src) const {
     285               0 :     return fRec == src.fRec || this->equals(src.c_str(), src.size());
     286                 : }
     287                 : 
     288               0 : bool SkString::equals(const char text[]) const {
     289               0 :     return this->equals(text, text ? strlen(text) : 0);
     290                 : }
     291                 : 
     292               0 : bool SkString::equals(const char text[], size_t len) const {
     293               0 :     SkASSERT(len == 0 || text != NULL);
     294                 : 
     295               0 :     return fRec->fLength == len && !memcmp(fRec->data(), text, len);
     296                 : }
     297                 : 
     298               0 : SkString& SkString::operator=(const SkString& src) {
     299               0 :     this->validate();
     300                 : 
     301               0 :     if (fRec != src.fRec) {
     302               0 :         SkString    tmp(src);
     303               0 :         this->swap(tmp);
     304                 :     }
     305               0 :     return *this;
     306                 : }
     307                 : 
     308               0 : SkString& SkString::operator=(const char text[]) {
     309               0 :     this->validate();
     310                 : 
     311               0 :     SkString tmp(text);
     312               0 :     this->swap(tmp);
     313                 : 
     314               0 :     return *this;
     315                 : }
     316                 : 
     317               0 : void SkString::reset() {
     318               0 :     this->validate();
     319                 : 
     320               0 :     if (fRec->fLength) {
     321               0 :         SkASSERT(fRec->fRefCnt > 0);
     322               0 :         if (sk_atomic_dec(&fRec->fRefCnt) == 1) {
     323               0 :             sk_free(fRec);
     324                 :         }
     325                 :     }
     326                 : 
     327               0 :     fRec = const_cast<Rec*>(&gEmptyRec);
     328                 : #ifdef SK_DEBUG
     329               0 :     fStr = fRec->data();
     330                 : #endif
     331               0 : }
     332                 : 
     333               0 : char* SkString::writable_str() {
     334               0 :     this->validate();
     335                 : 
     336               0 :     if (fRec->fLength) {
     337               0 :         if (fRec->fRefCnt > 1) {
     338               0 :             Rec* rec = AllocRec(fRec->data(), fRec->fLength);
     339               0 :             if (sk_atomic_dec(&fRec->fRefCnt) == 1) {
     340                 :                 // In this case after our check of fRecCnt > 1, we suddenly
     341                 :                 // did become the only owner, so now we have two copies of the
     342                 :                 // data (fRec and rec), so we need to delete one of them.
     343               0 :                 sk_free(fRec);
     344                 :             }
     345               0 :             fRec = rec;
     346                 :         #ifdef SK_DEBUG
     347               0 :             fStr = fRec->data();
     348                 :         #endif
     349                 :         }
     350                 :     }
     351               0 :     return fRec->data();
     352                 : }
     353                 : 
     354               0 : void SkString::set(const char text[]) {
     355               0 :     this->set(text, text ? strlen(text) : 0);
     356               0 : }
     357                 : 
     358               0 : void SkString::set(const char text[], size_t len) {
     359               0 :     if (0 == len) {
     360               0 :         this->reset();
     361               0 :     } else if (1 == fRec->fRefCnt && len <= fRec->fLength) {
     362                 :         // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1))?
     363                 :         // just use less of the buffer without allocating a smaller one
     364               0 :         char* p = this->writable_str();
     365               0 :         if (text) {
     366               0 :             memcpy(p, text, len);
     367                 :         }
     368               0 :         p[len] = 0;
     369               0 :         fRec->fLength = len;
     370               0 :     } else if (1 == fRec->fRefCnt && (fRec->fLength >> 2) == (len >> 2)) {
     371                 :         // we have spare room in the current allocation, so don't alloc a larger one
     372               0 :         char* p = this->writable_str();
     373               0 :         if (text) {
     374               0 :             memcpy(p, text, len);
     375                 :         }
     376               0 :         p[len] = 0;
     377               0 :         fRec->fLength = len;
     378                 :     } else {
     379               0 :         SkString tmp(text, len);
     380               0 :         this->swap(tmp);
     381                 :     }
     382               0 : }
     383                 : 
     384               0 : void SkString::setUTF16(const uint16_t src[]) {
     385               0 :     int count = 0;
     386                 : 
     387               0 :     while (src[count]) {
     388               0 :         count += 1;
     389                 :     }
     390               0 :     setUTF16(src, count);
     391               0 : }
     392                 : 
     393               0 : void SkString::setUTF16(const uint16_t src[], size_t count) {
     394               0 :     if (0 == count) {
     395               0 :         this->reset();
     396               0 :     } else if (count <= fRec->fLength) {
     397                 :         // should we resize if len <<<< fLength, to save RAM? (e.g. len < (fLength>>1))
     398               0 :         if (count < fRec->fLength) {
     399               0 :             this->resize(count);
     400                 :         }
     401               0 :         char* p = this->writable_str();
     402               0 :         for (size_t i = 0; i < count; i++) {
     403               0 :             p[i] = SkToU8(src[i]);
     404                 :         }
     405               0 :         p[count] = 0;
     406                 :     } else {
     407               0 :         SkString tmp(count); // puts a null terminator at the end of the string
     408               0 :         char*    p = tmp.writable_str();
     409                 : 
     410               0 :         for (size_t i = 0; i < count; i++) {
     411               0 :             p[i] = SkToU8(src[i]);
     412                 :         }
     413               0 :         this->swap(tmp);
     414                 :     }
     415               0 : }
     416                 : 
     417               0 : void SkString::insert(size_t offset, const char text[]) {
     418               0 :     this->insert(offset, text, text ? strlen(text) : 0);
     419               0 : }
     420                 : 
     421               0 : void SkString::insert(size_t offset, const char text[], size_t len) {
     422               0 :     if (len) {
     423               0 :         size_t length = fRec->fLength;
     424               0 :         if (offset > length) {
     425               0 :             offset = length;
     426                 :         }
     427                 : 
     428                 :         /*  If we're the only owner, and we have room in our allocation for the insert,
     429                 :             do it in place, rather than allocating a new buffer.
     430                 : 
     431                 :             To know we have room, compare the allocated sizes
     432                 :             beforeAlloc = SkAlign4(length + 1)
     433                 :             afterAlloc  = SkAligh4(length + 1 + len)
     434                 :             but SkAlign4(x) is (x + 3) >> 2 << 2
     435                 :             which is equivalent for testing to (length + 1 + 3) >> 2 == (length + 1 + 3 + len) >> 2
     436                 :             and we can then eliminate the +1+3 since that doesn't affec the answer
     437                 :         */
     438               0 :         if (1 == fRec->fRefCnt && (length >> 2) == ((length + len) >> 2)) {
     439               0 :             char* dst = this->writable_str();
     440                 : 
     441               0 :             if (offset < length) {
     442               0 :                 memmove(dst + offset + len, dst + offset, length - offset);
     443                 :             }
     444               0 :             memcpy(dst + offset, text, len);
     445                 : 
     446               0 :             dst[length + len] = 0;
     447               0 :             fRec->fLength = length + len;
     448                 :         } else {
     449                 :             /*  Seems we should use realloc here, since that is safe if it fails
     450                 :                 (we have the original data), and might be faster than alloc/copy/free.
     451                 :             */
     452               0 :             SkString    tmp(fRec->fLength + len);
     453               0 :             char*       dst = tmp.writable_str();
     454                 : 
     455               0 :             if (offset > 0) {
     456               0 :                 memcpy(dst, fRec->data(), offset);
     457                 :             }
     458               0 :             memcpy(dst + offset, text, len);
     459               0 :             if (offset < fRec->fLength) {
     460               0 :                 memcpy(dst + offset + len, fRec->data() + offset,
     461               0 :                        fRec->fLength - offset);
     462                 :             }
     463                 : 
     464               0 :             this->swap(tmp);
     465                 :         }
     466                 :     }
     467               0 : }
     468                 : 
     469               0 : void SkString::insertUnichar(size_t offset, SkUnichar uni) {
     470                 :     char    buffer[kMaxBytesInUTF8Sequence];
     471               0 :     size_t  len = SkUTF8_FromUnichar(uni, buffer);
     472                 : 
     473               0 :     if (len) {
     474               0 :         this->insert(offset, buffer, len);
     475                 :     }
     476               0 : }
     477                 : 
     478               0 : void SkString::insertS32(size_t offset, int32_t dec) {
     479                 :     char    buffer[SkStrAppendS32_MaxSize];
     480               0 :     char*   stop = SkStrAppendS32(buffer, dec);
     481               0 :     this->insert(offset, buffer, stop - buffer);
     482               0 : }
     483                 : 
     484               0 : void SkString::insertS64(size_t offset, int64_t dec, int minDigits) {
     485                 :     char    buffer[SkStrAppendS64_MaxSize];
     486               0 :     char*   stop = SkStrAppendS64(buffer, dec, minDigits);
     487               0 :     this->insert(offset, buffer, stop - buffer);
     488               0 : }
     489                 : 
     490               0 : void SkString::insertHex(size_t offset, uint32_t hex, int minDigits) {
     491               0 :     minDigits = SkPin32(minDigits, 0, 8);
     492                 : 
     493                 :     static const char gHex[] = "0123456789ABCDEF";
     494                 : 
     495                 :     char    buffer[8];
     496               0 :     char*   p = buffer + sizeof(buffer);
     497                 : 
     498               0 :     do {
     499               0 :         *--p = gHex[hex & 0xF];
     500               0 :         hex >>= 4;
     501               0 :         minDigits -= 1;
     502                 :     } while (hex != 0);
     503                 : 
     504               0 :     while (--minDigits >= 0) {
     505               0 :         *--p = '0';
     506                 :     }
     507                 : 
     508               0 :     SkASSERT(p >= buffer);
     509               0 :     this->insert(offset, p, buffer + sizeof(buffer) - p);
     510               0 : }
     511                 : 
     512               0 : void SkString::insertScalar(size_t offset, SkScalar value) {
     513                 :     char    buffer[SkStrAppendScalar_MaxSize];
     514               0 :     char*   stop = SkStrAppendScalar(buffer, value);
     515               0 :     this->insert(offset, buffer, stop - buffer);
     516               0 : }
     517                 : 
     518               0 : void SkString::printf(const char format[], ...) {
     519                 :     char    buffer[kBufferSize];
     520               0 :     ARGS_TO_BUFFER(format, buffer, kBufferSize);
     521                 : 
     522               0 :     this->set(buffer, strlen(buffer));
     523               0 : }
     524                 : 
     525               0 : void SkString::appendf(const char format[], ...) {
     526                 :     char    buffer[kBufferSize];
     527               0 :     ARGS_TO_BUFFER(format, buffer, kBufferSize);
     528                 : 
     529               0 :     this->append(buffer, strlen(buffer));
     530               0 : }
     531                 : 
     532               0 : void SkString::prependf(const char format[], ...) {
     533                 :     char    buffer[kBufferSize];
     534               0 :     ARGS_TO_BUFFER(format, buffer, kBufferSize);
     535                 : 
     536               0 :     this->prepend(buffer, strlen(buffer));
     537               0 : }
     538                 : 
     539                 : ///////////////////////////////////////////////////////////////////////////////
     540                 : 
     541               0 : void SkString::remove(size_t offset, size_t length) {
     542               0 :     size_t size = this->size();
     543                 : 
     544               0 :     if (offset < size) {
     545               0 :         if (offset + length > size) {
     546               0 :             length = size - offset;
     547                 :         }
     548               0 :         if (length > 0) {
     549               0 :             SkASSERT(size > length);
     550               0 :             SkString    tmp(size - length);
     551               0 :             char*       dst = tmp.writable_str();
     552               0 :             const char* src = this->c_str();
     553                 : 
     554               0 :             if (offset) {
     555               0 :                 SkASSERT(offset <= tmp.size());
     556               0 :                 memcpy(dst, src, offset);
     557                 :             }
     558               0 :             size_t tail = size - offset - length;
     559               0 :             SkASSERT((int32_t)tail >= 0);
     560               0 :             if (tail) {
     561                 :         //      SkASSERT(offset + length <= tmp.size());
     562               0 :                 memcpy(dst + offset, src + offset + length, tail);
     563                 :             }
     564               0 :             SkASSERT(dst[tmp.size()] == 0);
     565               0 :             this->swap(tmp);
     566                 :         }
     567                 :     }
     568               0 : }
     569                 : 
     570               0 : void SkString::swap(SkString& other) {
     571               0 :     this->validate();
     572               0 :     other.validate();
     573                 : 
     574               0 :     SkTSwap<Rec*>(fRec, other.fRec);
     575                 : #ifdef SK_DEBUG
     576               0 :     SkTSwap<const char*>(fStr, other.fStr);
     577                 : #endif
     578               0 : }
     579                 : 
     580                 : ///////////////////////////////////////////////////////////////////////////////
     581                 : 
     582               0 : SkAutoUCS2::SkAutoUCS2(const char utf8[]) {
     583               0 :     size_t len = strlen(utf8);
     584               0 :     fUCS2 = (uint16_t*)sk_malloc_throw((len + 1) * sizeof(uint16_t));
     585                 : 
     586               0 :     uint16_t* dst = fUCS2;
     587               0 :     for (;;) {
     588               0 :         SkUnichar uni = SkUTF8_NextUnichar(&utf8);
     589               0 :         *dst++ = SkToU16(uni);
     590               0 :         if (uni == 0) {
     591                 :             break;
     592                 :         }
     593                 :     }
     594               0 :     fCount = (int)(dst - fUCS2);
     595               0 : }
     596                 : 
     597               0 : SkAutoUCS2::~SkAutoUCS2() {
     598               0 :     sk_free(fUCS2);
     599               0 : }
     600                 : 
     601                 : ///////////////////////////////////////////////////////////////////////////////
     602                 : 
     603               0 : SkString SkStringPrintf(const char* format, ...) {
     604               0 :     SkString formattedOutput;
     605                 :     char buffer[kBufferSize];
     606               0 :     ARGS_TO_BUFFER(format, buffer, kBufferSize);
     607               0 :     formattedOutput.set(buffer);
     608                 :     return formattedOutput;
     609                 : }
     610                 : 
     611                 : #undef VSNPRINTF
     612                 : #undef SNPRINTF
     613                 : 

Generated by: LCOV version 1.7