• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / sitemesh2 / 59

22 Mar 2026 02:30AM UTC coverage: 40.347%. Remained the same
59

push

github

hazendaz
[mvn] Update maven wrapper

698 of 1891 branches covered (36.91%)

Branch coverage included in aggregate %.

1555 of 3693 relevant lines covered (42.11%)

0.42 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.09
/src/main/java/com/opensymphony/module/sitemesh/html/util/CharArray.java
1
/*
2
 * SPDX-License-Identifier: Apache-2.0
3
 * Copyright 2011-2026 Hazendaz
4
 */
5
package com.opensymphony.module.sitemesh.html.util;
6

7
import java.io.PrintWriter;
8

9
/**
10
 * A leaner, meaner version of StringBuilder.
11
 * <p>
12
 * It provides basic functionality to handle dynamically-growing char arrays as quickly as possible. This class is not
13
 * threadsafe.
14
 *
15
 * @author Chris Miller
16
 */
17
public class CharArray {
18

19
    /** The size. */
20
    int size = 0;
1✔
21

22
    /** The buffer. */
23
    char[] buffer;
24

25
    // These properties allow us to specify a substring within the character array
26
    // that we can perform comparisons against. This is here purely for performance -
27
    // the comparisons are at the heart of the FastPageParser loop and any speed increase
28
    /** The sub str start. */
29
    // we can get at this level has a huge impact on performance.
30
    int subStrStart = 0;
1✔
31

32
    /** The sub str len. */
33
    int subStrLen = 0;
1✔
34

35
    /**
36
     * Constructs a CharArray that is initialized to the specified size. Do not pass in a negative value because there
37
     * is no bounds checking!
38
     *
39
     * @param size
40
     *            the size
41
     */
42
    public CharArray(int size) {
1✔
43
        buffer = new char[size];
1✔
44
    }
1✔
45

46
    /**
47
     * Returns a String represenation of the character array.
48
     */
49
    @Override
50
    public String toString() {
51
        return new String(buffer, 0, size);
1✔
52
    }
53

54
    /**
55
     * Returns the character that is at the specified position in the array. There is no bounds checking on this method
56
     * so be sure to pass in a sensible value.
57
     *
58
     * @param pos
59
     *            the pos
60
     *
61
     * @return the char
62
     */
63
    public char charAt(int pos) {
64
        return buffer[pos];
1✔
65
    }
66

67
    /**
68
     * Changes the size of the character array to the value specified. If the new size is less than the current size,
69
     * the data in the internal array will be truncated. If the new size is &lt;= 0, the array will be reset to empty
70
     * (but, unlike StringBuilder, the internal array will NOT be shrunk). If the new size is &gt; the current size, the
71
     * array will be padded out with null characters (<code>'&#92;u0000'</code>).
72
     *
73
     * @param newSize
74
     *            the new size of the character array
75
     */
76
    public void setLength(int newSize) {
77
        if (newSize < 0) {
1!
78
            newSize = 0;
×
79
        }
80

81
        if (newSize <= size) {
1!
82
            size = newSize;
1✔
83
        } else {
84
            if (newSize >= buffer.length) {
×
85
                grow(newSize);
×
86
            }
87
            // Pad the array
88
            for (; size < newSize; size++) {
×
89
                buffer[size] = '\0';
×
90
            }
91
        }
92
    }
1✔
93

94
    /**
95
     * Returns the current length of the character array.
96
     *
97
     * @return the int
98
     */
99
    public int length() {
100
        return size;
1✔
101
    }
102

103
    /**
104
     * Appends an existing CharArray on to this one. Passing in a <code>null</code> CharArray will result in a
105
     * <code>NullPointerException</code>.
106
     *
107
     * @param chars
108
     *            the chars
109
     *
110
     * @return the char array
111
     */
112
    public CharArray append(CharArray chars) {
113
        return append(chars.buffer, 0, chars.size);
1✔
114
    }
115

116
    /**
117
     * Appends the supplied characters to the end of the array.
118
     *
119
     * @param chars
120
     *            the chars
121
     *
122
     * @return the char array
123
     */
124
    public CharArray append(char[] chars) {
125
        return append(chars, 0, chars.length);
×
126
    }
127

128
    /**
129
     * Append.
130
     *
131
     * @param chars
132
     *            the chars
133
     * @param position
134
     *            the position
135
     * @param length
136
     *            the length
137
     *
138
     * @return the char array
139
     */
140
    public CharArray append(char[] chars, int position, int length) {
141
        int requiredSize = length + size;
1✔
142
        if (requiredSize >= buffer.length) {
1!
143
            grow(requiredSize);
×
144
        }
145
        System.arraycopy(chars, position, buffer, size, length);
1✔
146
        size = requiredSize;
1✔
147
        return this;
1✔
148
    }
149

150
    /**
151
     * Appends a single character to the end of the character array.
152
     *
153
     * @param c
154
     *            the c
155
     *
156
     * @return the char array
157
     */
158
    public CharArray append(char c) {
159
        if (buffer.length == size) {
1!
160
            grow(0);
×
161
        }
162
        buffer[size++] = c;
1✔
163
        return this;
1✔
164
    }
165

166
    /**
167
     * Appends the supplied string to the end of this character array. Passing in a <code>null</code> string will result
168
     * in a <code>NullPointerException</code>.
169
     *
170
     * @param str
171
     *            the str
172
     *
173
     * @return the char array
174
     */
175
    public CharArray append(String str) {
176
        int requiredSize = str.length() + size;
1✔
177
        if (requiredSize >= buffer.length) {
1✔
178
            grow(requiredSize);
1✔
179
        }
180

181
        for (int i = 0; i < str.length(); i++) {
1✔
182
            buffer[size + i] = str.charAt(i);
1✔
183
        }
184

185
        size = requiredSize;
1✔
186
        return this;
1✔
187
    }
188

189
    /**
190
     * Returns a substring from within this character array. Note that NO range checking is performed!
191
     *
192
     * @param begin
193
     *            the begin
194
     * @param end
195
     *            the end
196
     *
197
     * @return the string
198
     */
199
    public String substring(int begin, int end) {
200
        return new String(buffer, begin, end - begin);
1✔
201
    }
202

203
    /**
204
     * Allows an arbitrary substring of this character array to be specified. This method should be called prior to
205
     * calling {@link #compareLowerSubstr(String)} to set the range of the substring comparison.
206
     *
207
     * @param begin
208
     *            the starting offset into the character array.
209
     * @param end
210
     *            the ending offset into the character array.
211
     */
212
    public void setSubstr(int begin, int end) {
213
        subStrStart = begin;
1✔
214
        subStrLen = end - begin;
1✔
215
    }
1✔
216

217
    /**
218
     * Returns the substring that was specified by the {@link #setSubstr(int, int)} call.
219
     *
220
     * @return the lower substr
221
     */
222
    public String getLowerSubstr() {
223
        for (int i = subStrStart; i < subStrStart + subStrLen; i++) {
1✔
224
            buffer[i] |= 32;
1✔
225
        }
226
        return new String(buffer, subStrStart, subStrLen);
1✔
227
    }
228

229
    /**
230
     * This compares a substring of this character array (as specified by the {@link #setSubstr(int, int)} method call)
231
     * with the supplied string. The supplied string <em>must</em> be lowercase, otherwise the comparison will fail.
232
     *
233
     * @param lowerStr
234
     *            the lower str
235
     *
236
     * @return true, if successful
237
     */
238
    public boolean compareLowerSubstr(String lowerStr) {
239
        // Range check
240
        if (lowerStr.length() != subStrLen || subStrLen <= 0) {
1!
241
            return false;
1✔
242
        }
243

244
        for (int i = 0; i < lowerStr.length(); i++) {
1✔
245
            // | 32 converts from ASCII uppercase to ASCII lowercase
246
            if ((buffer[subStrStart + i] | 32) != lowerStr.charAt(i)) {
1!
247
                return false;
×
248
            }
249
        }
250
        return true;
1✔
251
    }
252

253
    /**
254
     * Returns the hashcode for a <em>lowercase</em> version of the array's substring (as set by the
255
     * {@link #setSubstr(int, int)} method). This uses the same calculation as the <code>String.hashCode()</code> method
256
     * so that it remains compatible with the hashcodes of normal strings.
257
     *
258
     * @return the int
259
     */
260
    public int substrHashCode() {
261
        int hash = 0;
1✔
262
        int offset = subStrStart;
1✔
263
        for (int i = 0; i < subStrLen; i++) {
1✔
264
            hash = 31 * hash + (buffer[offset] | 32);
1✔
265
            offset++;
1✔
266
        }
267
        return hash;
1✔
268
    }
269

270
    /**
271
     * Compares the supplied uppercase string with the contents of the character array, starting at the offset
272
     * specified. This is a specialized method to help speed up the FastPageParser slightly.
273
     * <p>
274
     * The supplied string is assumed to contain only uppercase ASCII characters. The offset indicates the offset into
275
     * the character array that the comparison should start from.
276
     * <p>
277
     * If (and only if) the supplied string and the relevant portion of the character array are considered equal, this
278
     * method will return <code>true</code>.
279
     *
280
     * @param lowerStr
281
     *            the lower str
282
     * @param offset
283
     *            the offset
284
     *
285
     * @return true, if successful
286
     */
287
    public boolean compareLower(String lowerStr, int offset) {
288
        // Range check
289
        if (offset < 0 || offset + lowerStr.length() > size) {
×
290
            return false;
×
291
        }
292

293
        for (int i = 0; i < lowerStr.length(); i++) {
×
294
            // | 32 converts from ASCII uppercase to ASCII lowercase
295
            if ((buffer[offset + i] | 32) != lowerStr.charAt(i)) {
×
296
                return false;
×
297
            }
298
        }
299
        return true;
×
300
    }
301

302
    /**
303
     * Grows the internal array by either ~100% or minSize (whichever is larger), up to a maximum size of
304
     * Integer.MAX_VALUE.
305
     *
306
     * @param minSize
307
     *            the min size
308
     */
309
    private final void grow(int minSize) {
310
        int newCapacity = (buffer.length + 1) * 2;
1✔
311
        if (newCapacity < 0) {
1!
312
            newCapacity = Integer.MAX_VALUE;
×
313
        } else if (minSize > newCapacity) {
1!
314
            newCapacity = minSize;
×
315
        }
316
        char newBuffer[] = new char[newCapacity];
1✔
317
        System.arraycopy(buffer, 0, newBuffer, 0, size);
1✔
318
        buffer = newBuffer;
1✔
319
    }
1✔
320

321
    /**
322
     * Clear the contents.
323
     */
324
    public final void clear() {
325
        size = 0;
1✔
326
    }
1✔
327

328
    /**
329
     * Write to.
330
     *
331
     * @param writer
332
     *            the writer
333
     */
334
    public void writeTo(PrintWriter writer) {
335
        writer.write(buffer, 0, size);
×
336
    }
×
337
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc