1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project
48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */
88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkString_DEFINED
118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkString_DEFINED
128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScalar.h"
14d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com#include "SkTArray.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
16b9cf393e84a5f0e6dd6f570e4027b5d0c205f982bsalomon@google.com#include <stdarg.h>
17b9cf393e84a5f0e6dd6f570e4027b5d0c205f982bsalomon@google.com
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/*  Some helper functions for C strings
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
21e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.comstatic bool SkStrStartsWith(const char string[], const char prefixStr[]) {
22c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com    SkASSERT(string);
23e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    SkASSERT(prefixStr);
24e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    return !strncmp(string, prefixStr, strlen(prefixStr));
25c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com}
26e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.comstatic bool SkStrStartsWith(const char string[], const char prefixChar) {
27e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    SkASSERT(string);
28e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    return (prefixChar == *string);
29e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com}
30e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com
31e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.combool SkStrEndsWith(const char string[], const char suffixStr[]);
32e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.combool SkStrEndsWith(const char string[], const char suffixChar);
33e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comint SkStrStartsWithOneOf(const char string[], const char prefixes[]);
35e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com
367af56bee17764a0c118c8856a035bb3d27766969humper@google.comstatic int SkStrFind(const char string[], const char substring[]) {
3761a972f11f60a84ec0faadd6c33f77e690317a98humper@google.com    const char *first = strstr(string, substring);
387af56bee17764a0c118c8856a035bb3d27766969humper@google.com    if (NULL == first) return -1;
393d5b998bd7415d23469360425b0d5ddbf3f284ccreed@google.com    return SkToS32(first - &string[0]);
407af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
417af56bee17764a0c118c8856a035bb3d27766969humper@google.com
42c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.comstatic bool SkStrContains(const char string[], const char substring[]) {
43c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com    SkASSERT(string);
44c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com    SkASSERT(substring);
457af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return (-1 != SkStrFind(string, substring));
46c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com}
47e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.comstatic bool SkStrContains(const char string[], const char subchar) {
48e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    SkASSERT(string);
497af56bee17764a0c118c8856a035bb3d27766969humper@google.com    char tmp[2];
507af56bee17764a0c118c8856a035bb3d27766969humper@google.com    tmp[0] = subchar;
517af56bee17764a0c118c8856a035bb3d27766969humper@google.com    tmp[1] = '\0';
527af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return (-1 != SkStrFind(string, tmp));
537af56bee17764a0c118c8856a035bb3d27766969humper@google.com}
547af56bee17764a0c118c8856a035bb3d27766969humper@google.com
557af56bee17764a0c118c8856a035bb3d27766969humper@google.comstatic inline char *SkStrDup(const char string[]) {
567af56bee17764a0c118c8856a035bb3d27766969humper@google.com    char *ret = (char *) sk_malloc_throw(strlen(string)+1);
5737ebe3fbf6c4a5728bc2c322cc0f626444f987bfrobertphillips@google.com    memcpy(ret,string,strlen(string)+1);
587af56bee17764a0c118c8856a035bb3d27766969humper@google.com    return ret;
59e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com}
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
617af56bee17764a0c118c8856a035bb3d27766969humper@google.com
627af56bee17764a0c118c8856a035bb3d27766969humper@google.com
63d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com#define SkStrAppendU32_MaxSize  10
6427d302581a09d55cd8b2e64e42b23fceca66e33aepoger@google.comchar*   SkStrAppendU32(char buffer[], uint32_t);
65d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com#define SkStrAppendU64_MaxSize  20
6627d302581a09d55cd8b2e64e42b23fceca66e33aepoger@google.comchar*   SkStrAppendU64(char buffer[], uint64_t, int minDigits);
67d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com
68d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com#define SkStrAppendS32_MaxSize  (SkStrAppendU32_MaxSize + 1)
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comchar*   SkStrAppendS32(char buffer[], int32_t);
70d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com#define SkStrAppendS64_MaxSize  (SkStrAppendU64_MaxSize + 1)
71d877fdbb6e64692285c3e6532d88b9458f65b3cdvandebo@chromium.orgchar*   SkStrAppendS64(char buffer[], int64_t, int minDigits);
728072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com
738072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com/**
748072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com *  Floats have at most 8 significant digits, so we limit our %g to that.
75e280f1d164a7a4abba525276b7970666b1a50e0dreed@google.com *  However, the total string could be 15 characters: -1.2345678e-005
76e280f1d164a7a4abba525276b7970666b1a50e0dreed@google.com *
77e280f1d164a7a4abba525276b7970666b1a50e0dreed@google.com *  In theory we should only expect up to 2 digits for the exponent, but on
78e280f1d164a7a4abba525276b7970666b1a50e0dreed@google.com *  some platforms we have seen 3 (as in the example above).
798072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com */
80e280f1d164a7a4abba525276b7970666b1a50e0dreed@google.com#define SkStrAppendScalar_MaxSize  15
818072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com
828072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com/**
838072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com *  Write the scaler in decimal format into buffer, and return a pointer to
848072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com *  the next char after the last one written. Note: a terminating 0 is not
858072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com *  written into buffer, which must be at least SkStrAppendScalar_MaxSize.
868072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com *  Thus if the caller wants to add a 0 at the end, buffer must be at least
878072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com *  SkStrAppendScalar_MaxSize + 1 bytes large.
888072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com */
898f4d2306fa866a26f9448048ff63f692b2ba43aareed@google.com#define SkStrAppendScalar SkStrAppendFloat
90677cbedda7dc43844cbc58dbebbe52e37381be8evandebo@chromium.org
91677cbedda7dc43844cbc58dbebbe52e37381be8evandebo@chromium.orgchar* SkStrAppendFloat(char buffer[], float);
92677cbedda7dc43844cbc58dbebbe52e37381be8evandebo@chromium.orgchar* SkStrAppendFixed(char buffer[], SkFixed);
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** \class SkString
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Light weight class for managing strings. Uses reference
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    counting to make string assignments and copies very fast
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    with no extra RAM cost. Assumes UTF8 encoding.
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/
100a56fedc47af676f53e07e20b344f58e67c8d241evandebo@chromium.orgclass SK_API SkString {
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic:
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkString();
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    explicit    SkString(size_t len);
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    explicit    SkString(const char text[]);
1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                SkString(const char text[], size_t len);
1068015dd83ae37147bb630d4751030868051ad0caereed@android.com                SkString(const SkString&);
1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com                ~SkString();
1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1094bce115b316ec0ecc17e7b24ad7b1086fa3a8796reed@google.com    bool        isEmpty() const { return 0 == fRec->fLength; }
1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    size_t      size() const { return (size_t) fRec->fLength; }
1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const char* c_str() const { return fRec->data(); }
1128015dd83ae37147bb630d4751030868051ad0caereed@android.com    char operator[](size_t n) const { return this->c_str()[n]; }
1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1144e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    bool equals(const SkString&) const;
1154e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    bool equals(const char text[]) const;
1164e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    bool equals(const char text[], size_t len) const;
1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
118e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    bool startsWith(const char prefixStr[]) const {
119e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com        return SkStrStartsWith(fRec->data(), prefixStr);
120e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    }
121e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    bool startsWith(const char prefixChar) const {
122e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com        return SkStrStartsWith(fRec->data(), prefixChar);
1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
124e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    bool endsWith(const char suffixStr[]) const {
125e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com        return SkStrEndsWith(fRec->data(), suffixStr);
126e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    }
127e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    bool endsWith(const char suffixChar) const {
128e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com        return SkStrEndsWith(fRec->data(), suffixChar);
1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
130c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com    bool contains(const char substring[]) const {
131c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com        return SkStrContains(fRec->data(), substring);
132c4ae974db67977e766b66fb42e58e088c6381e29epoger@google.com    }
133e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    bool contains(const char subchar) const {
134e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com        return SkStrContains(fRec->data(), subchar);
135e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com    }
1367af56bee17764a0c118c8856a035bb3d27766969humper@google.com    int find(const char substring[]) const {
1377af56bee17764a0c118c8856a035bb3d27766969humper@google.com        return SkStrFind(fRec->data(), substring);
1387af56bee17764a0c118c8856a035bb3d27766969humper@google.com    }
1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
140b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com    friend bool operator==(const SkString& a, const SkString& b) {
1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return a.equals(b);
1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
143b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com    friend bool operator!=(const SkString& a, const SkString& b) {
1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        return !a.equals(b);
1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    // these methods edit the string
1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
149b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com    SkString& operator=(const SkString&);
150b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com    SkString& operator=(const char text[]);
1518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
152b530ef5869c5c64af8f3b3c62ed7711fe4325c9creed@google.com    char* writable_str();
1538015dd83ae37147bb630d4751030868051ad0caereed@android.com    char& operator[](size_t n) { return this->writable_str()[n]; }
1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1554e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void reset();
1564e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void resize(size_t len) { this->set(NULL, len); }
1574e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void set(const SkString& src) { *this = src; }
1584e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void set(const char text[]);
1594e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void set(const char text[], size_t len);
1604e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void setUTF16(const uint16_t[]);
1614e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void setUTF16(const uint16_t[], size_t len);
1624e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org
1634e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
1644e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insert(size_t offset, const char text[]);
1654e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insert(size_t offset, const char text[], size_t len);
1664e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insertUnichar(size_t offset, SkUnichar);
1674e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insertS32(size_t offset, int32_t value);
1684e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insertS64(size_t offset, int64_t value, int minDigits = 0);
169d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com    void insertU32(size_t offset, uint32_t value);
170d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com    void insertU64(size_t offset, uint64_t value, int minDigits = 0);
1714e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insertHex(size_t offset, uint32_t value, int minDigits = 0);
1724e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void insertScalar(size_t offset, SkScalar);
1734e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org
1744e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void append(const SkString& str) { this->insert((size_t)-1, str); }
1754e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void append(const char text[]) { this->insert((size_t)-1, text); }
1764e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
1774e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
1784e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
1794e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
180d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com    void appendU32(uint32_t value) { this->insertU32((size_t)-1, value); }
181d88a3d83364d2158a6fad9cb295012fac0e07ea3epoger@google.com    void appendU64(uint64_t value, int minDigits = 0) { this->insertU64((size_t)-1, value, minDigits); }
1824e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
1834e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
1844e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org
1854e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prepend(const SkString& str) { this->insert(0, str); }
1864e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prepend(const char text[]) { this->insert(0, text); }
1874e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prepend(const char text[], size_t len) { this->insert(0, text, len); }
1884e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
1894e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prependS32(int32_t value) { this->insertS32(0, value); }
1904e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
1914e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
1924e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
1934e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org
1943a67a668dbdc3a6bba68700a6dfdef8164ae0c69senorblanco@chromium.org    void printf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
1953a67a668dbdc3a6bba68700a6dfdef8164ae0c69senorblanco@chromium.org    void appendf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
196ce0e4efabd00b38aaaeb33457dcdb6c98e6eec12commit-bot@chromium.org    void appendVAList(const char format[], va_list);
1973a67a668dbdc3a6bba68700a6dfdef8164ae0c69senorblanco@chromium.org    void prependf(const char format[], ...) SK_PRINTF_LIKE(2, 3);
1984e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org
1994e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void remove(size_t offset, size_t length);
2004e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org
201fc296295257a9300098df56a1e3975580e13d329bsalomon@google.com    SkString& operator+=(const SkString& s) { this->append(s); return *this; }
202fc296295257a9300098df56a1e3975580e13d329bsalomon@google.com    SkString& operator+=(const char text[]) { this->append(text); return *this; }
2034a8084ced3fa5c73a364f96cadfa1fbfbea24ff6epoger@google.com    SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
204fc296295257a9300098df56a1e3975580e13d329bsalomon@google.com
2054e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    /**
2064e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org     *  Swap contents between this and other. This function is guaranteed
2074e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org     *  to never fail or throw.
2084e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org     */
2094e1d3acc16edb0b502cff157978235f5af627a5amike@reedtribe.org    void swap(SkString& other);
2108072e4fdc8261b1ca8937aa5c31db967280eae2areed@google.com
2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    struct Rec {
2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    public:
2148cb108803425481bf58f1eeb388cf818701c5e77reed@google.com        uint32_t    fLength; // logically size_t, but we want it to stay 32bits
2154bce115b316ec0ecc17e7b24ad7b1086fa3a8796reed@google.com        int32_t     fRefCnt;
2168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        char        fBeginningOfData;
2178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        char* data() { return &fBeginningOfData; }
2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        const char* data() const { return &fBeginningOfData; }
2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    };
2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Rec* fRec;
2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG
2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const char* fStr;
2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void validate() const;
2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else
2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    void validate() const {}
2288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
2298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static const Rec gEmptyRec;
2314bce115b316ec0ecc17e7b24ad7b1086fa3a8796reed@google.com    static Rec* AllocRec(const char text[], size_t len);
2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    static Rec* RefRec(Rec*);
2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
2348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
2353a1f6a06cc706b35d9d6086ffbf5135cbf42bf8atomhudson@google.com/// Creates a new string and writes into it using a printf()-style format.
2363a1f6a06cc706b35d9d6086ffbf5135cbf42bf8atomhudson@google.comSkString SkStringPrintf(const char* format, ...);
2373a1f6a06cc706b35d9d6086ffbf5135cbf42bf8atomhudson@google.com
238ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com// Specialized to take advantage of SkString's fast swap path. The unspecialized function is
239ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com// declared in SkTypes.h and called by SkTSort.
240ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.comtemplate <> inline void SkTSwap(SkString& a, SkString& b) {
241ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com    a.swap(b);
242ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com}
243ff436617d8f11297f0eff93ddd49fb9022d0843bbsalomon@google.com
244d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com// Split str on any characters in delimiters into out.  (Think, strtok with a sane API.)
245d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.comvoid SkStrSplit(const char* str, const char* delimiters, SkTArray<SkString>* out);
246d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com
2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif
248