blob: bcf124f337ac2c8180ccf74e596e7864f787bd1a [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
2 Copyright 2010 Google Inc.
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
18#ifndef GrStringBuilder_DEFINED
19#define GrStringBuilder_DEFINED
20
21#include <GrTArray.h>
22#include <stdio.h>
23
24// Class used to concat strings together into a single string
25// See below for GrSStringBuilder subclass that has a pool of
26// stack storage (to avoid malloc).
27class GrStringBuilder {
28public:
29 GrStringBuilder() :
30 fChars() {
31 fChars.push_back() = '\0';
32 }
33
34 GrStringBuilder(const GrStringBuilder& s) :
35 fChars(s.fChars) {
36 GrAssert('\0' == s.fChars.back());
37 }
38
39 GrStringBuilder(const char* s) :
40 fChars(s, strlen(s)+1) {
41 }
42
43 GrStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) {
44 GrAssert('\0' == a.fChars.back());
45 GrAssert('\0' == b.fChars.back());
46
47 fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
48 char* s = &fChars.front();
49 memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
50 s += a.fChars.count() - 1;
51 memcpy(s, &b.fChars.front(), b.fChars.count());
52 }
53
54 GrStringBuilder& operator =(const GrStringBuilder& s) {
55 fChars = s.fChars;
56 return *this;
57 }
58
59 GrStringBuilder& operator =(const char* s) {
60 GrAssert('\0' == fChars.back());
61
62 int l = strlen(s);
63 fChars.resize_back(l + 1);
64 memcpy(&fChars.front(), s, l + 1);
65 return *this;
66 }
67
68 GrStringBuilder& operator +=(const GrStringBuilder& s) {
69 GrAssert('\0' == fChars.back());
70 GrAssert('\0' == s.fChars.back());
71 fChars.push_back_n(s.length());
72 memcpy(&fChars.fromBack(s.length()), &s.fChars.front(), s.fChars.count());
73 return *this;
74 }
75
76 GrStringBuilder& operator +=(const char* s) {
77 GrAssert('\0' == fChars.back());
78 int l = strlen(s);
79 fChars.push_back_n(l);
80 memcpy(&fChars.fromBack(l), s, l + 1);
81 return *this;
82 }
83
84 GrStringBuilder& operator +=(char c) {
85 GrAssert('\0' == fChars.back());
86 fChars.back() = c;
87 fChars.push_back() = '\0';
88 return *this;
89 }
90
91 void appendInt(int x) {
92 GR_STATIC_ASSERT(4 == sizeof(int));
93 // -, 10 digits, null char
94 char temp[12];
95 sprintf(temp, "%d", x);
96 *this += temp;
97 }
98
99 char& operator [](int i) {
100 GrAssert(i < length());
101 return fChars[i];
102 }
103
104 char operator [](int i) const {
105 GrAssert(i < length());
106 return fChars[i];
107 }
108
109 const char* cstr() const { return &fChars.front(); }
110
111 int length() const { return fChars.count() - 1; }
112
113protected:
114 // helpers for GrSStringBuilder (with storage on the stack)
115
116 GrStringBuilder(void* stackChars, int stackCount) :
117 fChars(stackCount ? stackChars : NULL,
118 stackCount) {
119 fChars.push_back() = '\0';
120 }
121
122 GrStringBuilder(void* stackChars,
123 int stackCount,
124 const GrStringBuilder& s) :
125 fChars(s.fChars,
126 (stackCount ? stackChars : NULL),
127 stackCount) {
128 }
129
130 GrStringBuilder(void* stackChars,
131 int stackCount,
132 const char* s) :
133 fChars(s,
134 strlen(s)+1,
135 stackCount ? stackChars : NULL,
136 stackCount) {
137 }
138
139 GrStringBuilder(void* stackChars,
140 int stackCount,
141 const GrStringBuilder& a,
142 const GrStringBuilder& b) :
143 fChars(stackCount ? stackChars : NULL,
144 stackCount) {
145 GrAssert('\0' == a.fChars.back());
146 GrAssert('\0' == b.fChars.back());
147
148 fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
149 char* s = &fChars.front();
150 memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
151 s += a.fChars.count() - 1;
152 memcpy(s, &b.fChars.front(), b.fChars.count());
153 }
154
155private:
156 GrTArray<char, true> fChars;
157};
158
159template <int STACK_COUNT = 128>
160class GrSStringBuilder : public GrStringBuilder {
161public:
162 GrSStringBuilder() : GrStringBuilder(fStackChars, STACK_COUNT) {}
163
164 GrSStringBuilder(const GrStringBuilder& s) : GrStringBuilder(fStackChars,
165 STACK_COUNT,
166 s) {
167 }
168
169 GrSStringBuilder(const char* s) : GrStringBuilder(fStackChars,
170 STACK_COUNT,
171 s) {
172 }
173
174 GrSStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) :
175 GrStringBuilder(fStackChars, STACK_COUNT, a, b) {
176 }
177private:
178 char fStackChars[STACK_COUNT];
179};
180
181#endif
182