1
16 package io.netty.util.internal;
17
18
19 import java.util.Arrays;
20
21 public final class AppendableCharSequence implements CharSequence, Appendable {
22 private char[] chars;
23 private int pos;
24
25 public AppendableCharSequence(int length) {
26 if (length < 1) {
27 throw new IllegalArgumentException("length: " + length + " (length: >= 1)");
28 }
29 chars = new char[length];
30 }
31
32 private AppendableCharSequence(char[] chars) {
33 if (chars.length < 1) {
34 throw new IllegalArgumentException("length: " + chars.length + " (length: >= 1)");
35 }
36 this.chars = chars;
37 pos = chars.length;
38 }
39
40 public void setLength(int length) {
41 if (length < 0 || length > pos) {
42 throw new IllegalArgumentException("length: " + length + " (length: >= 0, <= " + pos + ')');
43 }
44 this.pos = length;
45 }
46
47 @Override
48 public int length() {
49 return pos;
50 }
51
52 @Override
53 public char charAt(int index) {
54 if (index > pos) {
55 throw new IndexOutOfBoundsException();
56 }
57 return chars[index];
58 }
59
60
67 public char charAtUnsafe(int index) {
68 return chars[index];
69 }
70
71 @Override
72 public AppendableCharSequence subSequence(int start, int end) {
73 if (start == end) {
74
75
76
77 return new AppendableCharSequence(Math.min(16, chars.length));
78 }
79 return new AppendableCharSequence(Arrays.copyOfRange(chars, start, end));
80 }
81
82 @Override
83 public AppendableCharSequence append(char c) {
84 if (pos == chars.length) {
85 char[] old = chars;
86 chars = new char[old.length << 1];
87 System.arraycopy(old, 0, chars, 0, old.length);
88 }
89 chars[pos++] = c;
90 return this;
91 }
92
93 @Override
94 public AppendableCharSequence append(CharSequence csq) {
95 return append(csq, 0, csq.length());
96 }
97
98 @Override
99 public AppendableCharSequence append(CharSequence csq, int start, int end) {
100 if (csq.length() < end) {
101 throw new IndexOutOfBoundsException("expected: csq.length() >= ("
102 + end + "),but actual is (" + csq.length() + ")");
103 }
104 int length = end - start;
105 if (length > chars.length - pos) {
106 chars = expand(chars, pos + length, pos);
107 }
108 if (csq instanceof AppendableCharSequence) {
109
110 AppendableCharSequence seq = (AppendableCharSequence) csq;
111 char[] src = seq.chars;
112 System.arraycopy(src, start, chars, pos, length);
113 pos += length;
114 return this;
115 }
116 for (int i = start; i < end; i++) {
117 chars[pos++] = csq.charAt(i);
118 }
119
120 return this;
121 }
122
123
127 public void reset() {
128 pos = 0;
129 }
130
131 @Override
132 public String toString() {
133 return new String(chars, 0, pos);
134 }
135
136
139 public String substring(int start, int end) {
140 int length = end - start;
141 if (start > pos || length > pos) {
142 throw new IndexOutOfBoundsException("expected: start and length <= ("
143 + pos + ")");
144 }
145 return new String(chars, start, length);
146 }
147
148
153 public String subStringUnsafe(int start, int end) {
154 return new String(chars, start, end - start);
155 }
156
157 private static char[] expand(char[] array, int neededSpace, int size) {
158 int newCapacity = array.length;
159 do {
160
161 newCapacity <<= 1;
162
163 if (newCapacity < 0) {
164 throw new IllegalStateException();
165 }
166
167 } while (neededSpace > newCapacity);
168
169 char[] newArray = new char[newCapacity];
170 System.arraycopy(array, 0, newArray, 0, size);
171
172 return newArray;
173 }
174 }
175