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