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