SkString.h revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
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 "SkScalar.h"
14
15/*  Some helper functions for C strings
16*/
17
18bool SkStrStartsWith(const char string[], const char prefix[]);
19bool SkStrEndsWith(const char string[], const char suffix[]);
20int SkStrStartsWithOneOf(const char string[], const char prefixes[]);
21
22#define SkStrAppendS32_MaxSize  11
23char*   SkStrAppendS32(char buffer[], int32_t);
24#define SkStrAppendS64_MaxSize  20
25char*   SkStrAppendS64(char buffer[], int64_t, int minDigits);
26
27/**
28 *  Floats have at most 8 significant digits, so we limit our %g to that.
29 *  However, the total string could be 15 characters: -1.2345678e-005
30 *
31 *  In theory we should only expect up to 2 digits for the exponent, but on
32 *  some platforms we have seen 3 (as in the example above).
33 */
34#define SkStrAppendScalar_MaxSize  15
35
36/**
37 *  Write the scaler in decimal format into buffer, and return a pointer to
38 *  the next char after the last one written. Note: a terminating 0 is not
39 *  written into buffer, which must be at least SkStrAppendScalar_MaxSize.
40 *  Thus if the caller wants to add a 0 at the end, buffer must be at least
41 *  SkStrAppendScalar_MaxSize + 1 bytes large.
42 */
43#ifdef SK_SCALAR_IS_FLOAT
44    #define SkStrAppendScalar SkStrAppendFloat
45#else
46    #define SkStrAppendScalar SkStrAppendFixed
47#endif
48
49#ifdef SK_CAN_USE_FLOAT
50char* SkStrAppendFloat(char buffer[], float);
51#endif
52char* SkStrAppendFixed(char buffer[], SkFixed);
53
54/** \class SkString
55
56    Light weight class for managing strings. Uses reference
57    counting to make string assignments and copies very fast
58    with no extra RAM cost. Assumes UTF8 encoding.
59*/
60class SkString {
61public:
62                SkString();
63    explicit    SkString(size_t len);
64    explicit    SkString(const char text[]);
65                SkString(const char text[], size_t len);
66                SkString(const SkString&);
67                ~SkString();
68
69    bool        isEmpty() const { return fRec->fLength == 0; }
70    size_t      size() const { return (size_t) fRec->fLength; }
71    const char* c_str() const { return fRec->data(); }
72    char operator[](size_t n) const { return this->c_str()[n]; }
73
74    bool equals(const SkString&) const;
75    bool equals(const char text[]) const;
76    bool equals(const char text[], size_t len) const;
77
78    bool startsWith(const char prefix[]) const {
79        return SkStrStartsWith(fRec->data(), prefix);
80    }
81    bool endsWith(const char suffix[]) const {
82        return SkStrEndsWith(fRec->data(), suffix);
83    }
84
85    friend bool operator==(const SkString& a, const SkString& b) {
86        return a.equals(b);
87    }
88    friend bool operator!=(const SkString& a, const SkString& b) {
89        return !a.equals(b);
90    }
91
92    // these methods edit the string
93
94    SkString& operator=(const SkString&);
95    SkString& operator=(const char text[]);
96
97    char* writable_str();
98    char& operator[](size_t n) { return this->writable_str()[n]; }
99
100    void reset();
101    void resize(size_t len) { this->set(NULL, len); }
102    void set(const SkString& src) { *this = src; }
103    void set(const char text[]);
104    void set(const char text[], size_t len);
105    void setUTF16(const uint16_t[]);
106    void setUTF16(const uint16_t[], size_t len);
107
108    void insert(size_t offset, const SkString& src) { this->insert(offset, src.c_str(), src.size()); }
109    void insert(size_t offset, const char text[]);
110    void insert(size_t offset, const char text[], size_t len);
111    void insertUnichar(size_t offset, SkUnichar);
112    void insertS32(size_t offset, int32_t value);
113    void insertS64(size_t offset, int64_t value, int minDigits = 0);
114    void insertHex(size_t offset, uint32_t value, int minDigits = 0);
115    void insertScalar(size_t offset, SkScalar);
116
117    void append(const SkString& str) { this->insert((size_t)-1, str); }
118    void append(const char text[]) { this->insert((size_t)-1, text); }
119    void append(const char text[], size_t len) { this->insert((size_t)-1, text, len); }
120    void appendUnichar(SkUnichar uni) { this->insertUnichar((size_t)-1, uni); }
121    void appendS32(int32_t value) { this->insertS32((size_t)-1, value); }
122    void appendS64(int64_t value, int minDigits = 0) { this->insertS64((size_t)-1, value, minDigits); }
123    void appendHex(uint32_t value, int minDigits = 0) { this->insertHex((size_t)-1, value, minDigits); }
124    void appendScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
125
126    void prepend(const SkString& str) { this->insert(0, str); }
127    void prepend(const char text[]) { this->insert(0, text); }
128    void prepend(const char text[], size_t len) { this->insert(0, text, len); }
129    void prependUnichar(SkUnichar uni) { this->insertUnichar(0, uni); }
130    void prependS32(int32_t value) { this->insertS32(0, value); }
131    void prependS64(int32_t value, int minDigits = 0) { this->insertS64(0, value, minDigits); }
132    void prependHex(uint32_t value, int minDigits = 0) { this->insertHex(0, value, minDigits); }
133    void prependScalar(SkScalar value) { this->insertScalar((size_t)-1, value); }
134
135    void printf(const char format[], ...);
136    void appendf(const char format[], ...);
137    void prependf(const char format[], ...);
138
139    void remove(size_t offset, size_t length);
140
141    SkString& operator+=(const SkString& s) { this->append(s); return *this; }
142    SkString& operator+=(const char text[]) { this->append(text); return *this; }
143    SkString& operator+=(const char c) { this->append(&c, 1); return *this; }
144
145    /**
146     *  Swap contents between this and other. This function is guaranteed
147     *  to never fail or throw.
148     */
149    void swap(SkString& other);
150
151private:
152    struct Rec {
153    public:
154        uint16_t    fLength;
155        uint16_t    fRefCnt;
156        char        fBeginningOfData;
157
158        char* data() { return &fBeginningOfData; }
159        const char* data() const { return &fBeginningOfData; }
160    };
161    Rec* fRec;
162
163#ifdef SK_DEBUG
164    const char* fStr;
165    void validate() const;
166#else
167    void validate() const {}
168#endif
169
170    static const Rec gEmptyRec;
171    static Rec* AllocRec(const char text[], U16CPU len);
172    static Rec* RefRec(Rec*);
173};
174
175class SkAutoUCS2 {
176public:
177    SkAutoUCS2(const char utf8[]);
178    ~SkAutoUCS2();
179
180    /** This returns the number of ucs2 characters
181    */
182    int count() const { return fCount; }
183
184    /** This returns a null terminated ucs2 string
185    */
186    const uint16_t* getUCS2() const { return fUCS2; }
187
188private:
189    int         fCount;
190    uint16_t*   fUCS2;
191};
192
193/// Creates a new string and writes into it using a printf()-style format.
194SkString SkStringPrintf(const char* format, ...);
195
196#endif
197