MIME4J-5 Performance patch 3, https://issues.apache.org/jira/browse/MIME4J-5. Contrib...
[mime4j.git] / src / main / java / org / apache / james / mime4j / CharArrayBuffer.java
blobfd9453f4d5e13a8535f71e672e2c1af39fec20e4
1 /****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one *
3 * or more contributor license agreements. See the NOTICE file *
4 * distributed with this work for additional information *
5 * regarding copyright ownership. The ASF licenses this file *
6 * to you under the Apache License, Version 2.0 (the *
7 * "License"); you may not use this file except in compliance *
8 * with the License. You may obtain a copy of the License at *
9 * *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, *
13 * software distributed under the License is distributed on an *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
15 * KIND, either express or implied. See the License for the *
16 * specific language governing permissions and limitations *
17 * under the License. *
18 ****************************************************************/
20 package org.apache.james.mime4j;
22 import org.apache.james.mime4j.util.MessageUtils;
24 /**
25 * A resizable char array.
28 public final class CharArrayBuffer {
30 private char[] buffer;
31 private int len;
33 public CharArrayBuffer(int capacity) {
34 super();
35 if (capacity < 0) {
36 throw new IllegalArgumentException("Buffer capacity may not be negative");
38 this.buffer = new char[capacity];
41 private void expand(int newlen) {
42 char newbuffer[] = new char[Math.max(this.buffer.length << 1, newlen)];
43 System.arraycopy(this.buffer, 0, newbuffer, 0, this.len);
44 this.buffer = newbuffer;
47 public void append(final char[] b, int off, int len) {
48 if (b == null) {
49 return;
51 if ((off < 0) || (off > b.length) || (len < 0) ||
52 ((off + len) < 0) || ((off + len) > b.length)) {
53 throw new IndexOutOfBoundsException();
55 if (len == 0) {
56 return;
58 int newlen = this.len + len;
59 if (newlen > this.buffer.length) {
60 expand(newlen);
62 System.arraycopy(b, off, this.buffer, this.len, len);
63 this.len = newlen;
66 public void append(String str) {
67 if (str == null) {
68 str = "null";
70 int strlen = str.length();
71 int newlen = this.len + strlen;
72 if (newlen > this.buffer.length) {
73 expand(newlen);
75 str.getChars(0, strlen, this.buffer, this.len);
76 this.len = newlen;
79 public void append(final CharArrayBuffer b, int off, int len) {
80 if (b == null) {
81 return;
83 append(b.buffer, off, len);
86 public void append(final CharArrayBuffer b) {
87 if (b == null) {
88 return;
90 append(b.buffer,0, b.len);
93 public void append(char ch) {
94 int newlen = this.len + 1;
95 if (newlen > this.buffer.length) {
96 expand(newlen);
98 this.buffer[this.len] = ch;
99 this.len = newlen;
102 public void append(final byte[] b, int off, int len) {
103 if (b == null) {
104 return;
106 if ((off < 0) || (off > b.length) || (len < 0) ||
107 ((off + len) < 0) || ((off + len) > b.length)) {
108 throw new IndexOutOfBoundsException();
110 if (len == 0) {
111 return;
113 int oldlen = this.len;
114 int newlen = oldlen + len;
115 if (newlen > this.buffer.length) {
116 expand(newlen);
118 for (int i1 = off, i2 = oldlen; i2 < newlen; i1++, i2++) {
119 int ch = b[i1];
120 if (ch < 0) {
121 ch = 256 + ch;
123 this.buffer[i2] = (char) ch;
125 this.len = newlen;
128 public void append(final ByteArrayBuffer b, int off, int len) {
129 if (b == null) {
130 return;
132 append(b.buffer(), off, len);
135 public void append(final Object obj) {
136 append(String.valueOf(obj));
139 public void clear() {
140 this.len = 0;
143 public char[] toCharArray() {
144 char[] b = new char[this.len];
145 if (this.len > 0) {
146 System.arraycopy(this.buffer, 0, b, 0, this.len);
148 return b;
151 public char charAt(int i) {
152 return this.buffer[i];
155 public char[] buffer() {
156 return this.buffer;
159 public int capacity() {
160 return this.buffer.length;
163 public int length() {
164 return this.len;
167 public void ensureCapacity(int required) {
168 int available = this.buffer.length - this.len;
169 if (required > available) {
170 expand(this.len + required);
174 public void setLength(int len) {
175 if (len < 0 || len > this.buffer.length) {
176 throw new IndexOutOfBoundsException();
178 this.len = len;
181 public boolean isEmpty() {
182 return this.len == 0;
185 public boolean isFull() {
186 return this.len == this.buffer.length;
189 public int indexOf(int ch, int beginIndex, int endIndex) {
190 if (beginIndex < 0) {
191 beginIndex = 0;
193 if (endIndex > this.len) {
194 endIndex = this.len;
196 if (beginIndex > endIndex) {
197 return -1;
199 for (int i = beginIndex; i < endIndex; i++) {
200 if (this.buffer[i] == ch) {
201 return i;
204 return -1;
207 public int indexOf(int ch) {
208 return indexOf(ch, 0, this.len);
211 public String substring(int beginIndex, int endIndex) {
212 if (beginIndex < 0) {
213 throw new IndexOutOfBoundsException();
215 if (endIndex > this.len) {
216 throw new IndexOutOfBoundsException();
218 if (beginIndex > endIndex) {
219 throw new IndexOutOfBoundsException();
221 return new String(this.buffer, beginIndex, endIndex - beginIndex);
224 public String substringTrimmed(int beginIndex, int endIndex) {
225 if (beginIndex < 0) {
226 throw new IndexOutOfBoundsException();
228 if (endIndex > this.len) {
229 throw new IndexOutOfBoundsException();
231 if (beginIndex > endIndex) {
232 throw new IndexOutOfBoundsException();
234 while (beginIndex < endIndex && MessageUtils.isWhitespace(this.buffer[beginIndex])) {
235 beginIndex++;
237 while (endIndex > beginIndex && MessageUtils.isWhitespace(this.buffer[endIndex - 1])) {
238 endIndex--;
240 return new String(this.buffer, beginIndex, endIndex - beginIndex);
243 public String toString() {
244 return new String(this.buffer, 0, this.len);