LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/core - SkString.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 58 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef SkString_DEFINED
      11             : #define SkString_DEFINED
      12             : 
      13             : #include "../private/SkTArray.h"
      14             : #include "SkScalar.h"
      15             : 
      16             : #include <stdarg.h>
      17             : 
      18             : /*  Some helper functions for C strings
      19             : */
      20             : 
      21           0 : static bool SkStrStartsWith(const char string[], const char prefixStr[]) {
      22           0 :     SkASSERT(string);
      23           0 :     SkASSERT(prefixStr);
      24           0 :     return !strncmp(string, prefixStr, strlen(prefixStr));
      25             : }
      26           0 : static bool SkStrStartsWith(const char string[], const char prefixChar) {
      27           0 :     SkASSERT(string);
      28           0 :     return (prefixChar == *string);
      29             : }
      30             : 
      31             : bool SkStrEndsWith(const char string[], const char suffixStr[]);
      32             : bool SkStrEndsWith(const char string[], const char suffixChar);
      33             : 
      34             : int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
      35             : 
      36           0 : static int SkStrFind(const char string[], const char substring[]) {
      37           0 :     const char *first = strstr(string, substring);
      38           0 :     if (NULL == first) return -1;
      39           0 :     return SkToInt(first - &string[0]);
      40             : }
      41             : 
      42           0 : static int SkStrFindLastOf(const char string[], const char subchar) {
      43           0 :     const char* last = strrchr(string, subchar);
      44           0 :     if (NULL == last) return -1;
      45           0 :     return SkToInt(last - &string[0]);
      46             : }
      47             : 
      48           0 : static bool SkStrContains(const char string[], const char substring[]) {
      49           0 :     SkASSERT(string);
      50           0 :     SkASSERT(substring);
      51           0 :     return (-1 != SkStrFind(string, substring));
      52             : }
      53           0 : static bool SkStrContains(const char string[], const char subchar) {
      54           0 :     SkASSERT(string);
      55             :     char tmp[2];
      56           0 :     tmp[0] = subchar;
      57           0 :     tmp[1] = '\0';
      58           0 :     return (-1 != SkStrFind(string, tmp));
      59             : }
      60             : 
      61             : static inline char *SkStrDup(const char string[]) {
      62             :     char *ret = (char *) sk_malloc_throw(strlen(string)+1);
      63             :     memcpy(ret,string,strlen(string)+1);
      64             :     return ret;
      65             : }
      66             : 
      67             : /*
      68             :  *  The SkStrAppend... methods will write into the provided buffer, assuming it is large enough.
      69             :  *  Each method has an associated const (e.g. SkStrAppendU32_MaxSize) which will be the largest
      70             :  *  value needed for that method's buffer.
      71             :  *
      72             :  *  char storage[SkStrAppendU32_MaxSize];
      73             :  *  SkStrAppendU32(storage, value);
      74             :  *
      75             :  *  Note : none of the SkStrAppend... methods write a terminating 0 to their buffers. Instead,
      76             :  *  the methods return the ptr to the end of the written part of the buffer. This can be used
      77             :  *  to compute the length, and/or know where to write a 0 if that is desired.
      78             :  *
      79             :  *  char storage[SkStrAppendU32_MaxSize + 1];
      80             :  *  char* stop = SkStrAppendU32(storage, value);
      81             :  *  size_t len = stop - storage;
      82             :  *  *stop = 0;   // valid, since storage was 1 byte larger than the max.
      83             :  */
      84             : 
      85             : #define SkStrAppendU32_MaxSize  10
      86             : char*   SkStrAppendU32(char buffer[], uint32_t);
      87             : #define SkStrAppendU64_MaxSize  20
      88             : char*   SkStrAppendU64(char buffer[], uint64_t, int minDigits);
      89             : 
      90             : #define SkStrAppendS32_MaxSize  (SkStrAppendU32_MaxSize + 1)
      91             : char*   SkStrAppendS32(char buffer[], int32_t);
      92             : #define SkStrAppendS64_MaxSize  (SkStrAppendU64_MaxSize + 1)
      93             : char*   SkStrAppendS64(char buffer[], int64_t, int minDigits);
      94             : 
      95             : /**
      96             :  *  Floats have at most 8 significant digits, so we limit our %g to that.
      97             :  *  However, the total string could be 15 characters: -1.2345678e-005
      98             :  *
      99             :  *  In theory we should only expect up to 2 digits for the exponent, but on
     100             :  *  some platforms we have seen 3 (as in the example above).
     101             :  */
     102             : #define SkStrAppendScalar_MaxSize  15
     103             : 
     104             : /**
     105             :  *  Write the scaler in decimal format into buffer, and return a pointer to
     106             :  *  the next char after the last one written. Note: a terminating 0 is not
     107             :  *  written into buffer, which must be at least SkStrAppendScalar_MaxSize.
     108             :  *  Thus if the caller wants to add a 0 at the end, buffer must be at least
     109             :  *  SkStrAppendScalar_MaxSize + 1 bytes large.
     110             :  */
     111             : #define SkStrAppendScalar SkStrAppendFloat
     112             : 
     113             : char* SkStrAppendFloat(char buffer[], float);
     114             : 
     115             : /** \class SkString
     116             : 
     117             :     Light weight class for managing strings. Uses reference
     118             :     counting to make string assignments and copies very fast
     119             :     with no extra RAM cost. Assumes UTF8 encoding.
     120             : */
     121             : class SK_API SkString {
     122             : public:
     123             :                 SkString();
     124             :     explicit    SkString(size_t len);
     125             :     explicit    SkString(const char text[]);
     126             :                 SkString(const char text[], size_t len);
     127             :                 SkString(const SkString&);
     128             :                 SkString(SkString&&);
     129             :                 ~SkString();
     130             : 
     131           0 :     bool        isEmpty() const { return 0 == fRec->fLength; }
     132           0 :     size_t      size() const { return (size_t) fRec->fLength; }
     133           0 :     const char* c_str() const { return fRec->data(); }
     134           0 :     char operator[](size_t n) const { return this->c_str()[n]; }
     135             : 
     136             :     bool equals(const SkString&) const;
     137             :     bool equals(const char text[]) const;
     138             :     bool equals(const char text[], size_t len) const;
     139             : 
     140             :     bool startsWith(const char prefixStr[]) const {
     141             :         return SkStrStartsWith(fRec->data(), prefixStr);
     142             :     }
     143             :     bool startsWith(const char prefixChar) const {
     144             :         return SkStrStartsWith(fRec->data(), prefixChar);
     145             :     }
     146           0 :     bool endsWith(const char suffixStr[]) const {
     147           0 :         return SkStrEndsWith(fRec->data(), suffixStr);
     148             :     }
     149           0 :     bool endsWith(const char suffixChar) const {
     150           0 :         return SkStrEndsWith(fRec->data(), suffixChar);
     151             :     }
     152             :     bool contains(const char substring[]) const {
     153             :         return SkStrContains(fRec->data(), substring);
     154             :     }
     155           0 :     bool contains(const char subchar) const {
     156           0 :         return SkStrContains(fRec->data(), subchar);
     157             :     }
     158             :     int find(const char substring[]) const {
     159             :         return SkStrFind(fRec->data(), substring);
     160             :     }
     161           0 :     int findLastOf(const char subchar) const {
     162           0 :         return SkStrFindLastOf(fRec->data(), subchar);
     163             :     }
     164             : 
     165           0 :     friend bool operator==(const SkString& a, const SkString& b) {
     166           0 :         return a.equals(b);
     167             :     }
     168             :     friend bool operator!=(const SkString& a, const SkString& b) {
     169             :         return !a.equals(b);
     170             :     }
     171             : 
     172             :     // these methods edit the string
     173             : 
     174             :     SkString& operator=(const SkString&);
     175             :     SkString& operator=(SkString&&);
     176             :     SkString& operator=(const char text[]);
     177             : 
     178             :     char* writable_str();
     179           0 :     char& operator[](size_t n) { return this->writable_str()[n]; }
     180             : 
     181             :     void reset();
     182             :     /** Destructive resize, does not preserve contents. */
     183           0 :     void resize(size_t len) { this->set(NULL, len); }
     184             :     void set(const SkString& src) { *this = src; }
     185             :     void set(const char text[]);
     186             :     void set(const char text[], size_t len);
     187             :     void setUTF16(const uint16_t[]);
     188             :     void setUTF16(const uint16_t[], size_t len);
     189             : 
     190           0 :     void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
     191             :     void insert(size_t offset, const char text[]);
     192             :     void insert(size_t offset, const char text[], size_t len);
     193             :     void insertUnichar(size_t offset, SkUnichar);
     194             :     void insertS32(size_t offset, int32_t value);
     195             :     void insertS64(size_t offset, int64_t value, int minDigits = 0);
     196             :     void insertU32(size_t offset, uint32_t value);
     197             :     void insertU64(size_t offset, uint64_t value, int minDigits = 0);
     198             :     void insertHex(size_t offset, uint32_t value, int minDigits = 0);
     199             :     void insertScalar(size_t offset, SkScalar);
     200             : 
     201           0 :     void append(const SkString& str) { this->insert((size_t)-1, str); }
     202           0 :     void append(const char text[]) { this->insert((size_t)-1, text); }
     203           0 :     void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
     204           0 :     void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
     205           0 :     void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
     206             :     void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
     207           0 :     void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
     208             :     void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
     209           0 :     void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
     210           0 :     void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
     211             : 
     212             :     void prepend(const SkString& str) { this->insert(0, str); }
     213             :     void prepend(const char text[]) { this->insert(0, text); }
     214           0 :     void prepend(const char text[], size_t len) { this->insert(0, text, len); }
     215             :     void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
     216             :     void prependS32(int32_t value) { this->insertS32(0, value); }
     217             :     void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
     218             :     void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
     219             :     void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
     220             : 
     221             :     void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
     222             :     void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
     223             :     void appendVAList(const char format[], va_list);
     224             :     void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
     225             :     void prependVAList(const char format[], va_list);
     226             : 
     227             :     void remove(size_t offset, size_t length);
     228             : 
     229           0 :     SkString& operator+=(const SkString& s) { this->append(s); return *this; }
     230           0 :     SkString& operator+=(const char text[]) { this->append(text); return *this; }
     231           0 :     SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
     232             : 
     233             :     /**
     234             :      *  Swap contents between this and other. This function is guaranteed
     235             :      *  to never fail or throw.
     236             :      */
     237             :     void swap(SkString& other);
     238             : 
     239             : private:
     240             :     struct Rec {
     241             :     public:
     242             :         uint32_t    fLength; // logically size_t, but we want it to stay 32bits
     243             :         int32_t     fRefCnt;
     244             :         char        fBeginningOfData;
     245             : 
     246           0 :         char* data() { return &fBeginningOfData; }
     247           0 :         const char* data() const { return &fBeginningOfData; }
     248             :     };
     249             :     Rec* fRec;
     250             : 
     251             : #ifdef SK_DEBUG
     252             :     void validate() const;
     253             : #else
     254             :     void validate() const {}
     255             : #endif
     256             : 
     257             :     static const Rec gEmptyRec;
     258             :     static Rec* AllocRec(const char text[], size_t len);
     259             :     static Rec* RefRec(Rec*);
     260             : };
     261             : 
     262             : /// Creates a new string and writes into it using a printf()-style format.
     263             : SkString SkStringPrintf(const char* format, ...);
     264             : 
     265             : // Specialized to take advantage of SkString's fast swap path. The unspecialized function is
     266             : // declared in SkTypes.h and called by SkTSort.
     267           0 : template <> inline void SkTSwap(SkString& a, SkString& b) {
     268           0 :     a.swap(b);
     269           0 : }
     270             : 
     271             : enum SkStrSplitMode {
     272             :     // Strictly return all results. If the input is ",," and the separator is ',' this will return
     273             :     // an array of three empty strings.
     274             :     kStrict_SkStrSplitMode,
     275             : 
     276             :     // Only nonempty results will be added to the results. Multiple separators will be
     277             :     // coalesced. Separators at the beginning and end of the input will be ignored.  If the input is
     278             :     // ",," and the separator is ',', this will return an empty vector.
     279             :     kCoalesce_SkStrSplitMode
     280             : };
     281             : 
     282             : // Split str on any characters in delimiters into out.  (Think, strtok with a sane API.)
     283             : void SkStrSplit(const char* str, const char* delimiters, SkStrSplitMode splitMode,
     284             :                 SkTArray<SkString>* out);
     285             : inline void SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out) {
     286             :     SkStrSplit(str, delimiters, kCoalesce_SkStrSplitMode, out);
     287             : }
     288             : 
     289             : #endif

Generated by: LCOV version 1.13