1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
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      @Override
41      public int length() {
42          return pos;
43      }
44  
45      @Override
46      public char charAt(int index) {
47          if (index > pos) {
48              throw new IndexOutOfBoundsException();
49          }
50          return chars[index];
51      }
52  
53      
54  
55  
56  
57  
58  
59  
60      public char charAtUnsafe(int index) {
61          return chars[index];
62      }
63  
64      @Override
65      public AppendableCharSequence subSequence(int start, int end) {
66          return new AppendableCharSequence(Arrays.copyOfRange(chars, start, end));
67      }
68  
69      @Override
70      public AppendableCharSequence append(char c) {
71          if (pos == chars.length) {
72              char[] old = chars;
73              chars = new char[old.length << 1];
74              System.arraycopy(old, 0, chars, 0, old.length);
75          }
76          chars[pos++] = c;
77          return this;
78      }
79  
80      @Override
81      public AppendableCharSequence append(CharSequence csq) {
82          return append(csq, 0, csq.length());
83      }
84  
85      @Override
86      public AppendableCharSequence append(CharSequence csq, int start, int end) {
87          if (csq.length() < end) {
88              throw new IndexOutOfBoundsException();
89          }
90          int length = end - start;
91          if (length > chars.length - pos) {
92              chars = expand(chars, pos + length, pos);
93          }
94          if (csq instanceof AppendableCharSequence) {
95              
96              AppendableCharSequence seq = (AppendableCharSequence) csq;
97              char[] src = seq.chars;
98              System.arraycopy(src, start, chars, pos, length);
99              pos += length;
100             return this;
101         }
102         for (int i = start; i < end; i++) {
103             chars[pos++] = csq.charAt(i);
104         }
105 
106         return this;
107     }
108 
109     
110 
111 
112 
113     public void reset() {
114         pos = 0;
115     }
116 
117     @Override
118     public String toString() {
119         return new String(chars, 0, pos);
120     }
121 
122     
123 
124 
125     public String substring(int start, int end) {
126         int length = end - start;
127         if (start > pos || length > pos) {
128             throw new IndexOutOfBoundsException();
129         }
130         return new String(chars, start, length);
131     }
132 
133     
134 
135 
136 
137 
138     public String subStringUnsafe(int start, int end) {
139         return new String(chars, start, end - start);
140     }
141 
142     private static char[] expand(char[] array, int neededSpace, int size) {
143         int newCapacity = array.length;
144         do {
145             
146             newCapacity <<= 1;
147 
148             if (newCapacity < 0) {
149                 throw new IllegalStateException();
150             }
151 
152         } while (neededSpace > newCapacity);
153 
154         char[] newArray = new char[newCapacity];
155         System.arraycopy(array, 0, newArray, 0, size);
156 
157         return newArray;
158     }
159 }