View Javadoc

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   */
19  package org.apache.commons.csv;
20  
21  /**
22   * A simple StringBuffer replacement that aims to 
23   * reduce copying as much as possible. The buffer
24   * grows as necessary.
25   * This class is not thread safe.
26   * 
27   * @author Ortwin Gl�ck
28   */
29  public class CharBuffer {
30  
31      private char[] c;
32  
33      /**
34       * Actually used number of characters in the array. 
35       * It is also the index at which
36       * a new character will be inserted into <code>c</code>. 
37       */ 
38      private int length;
39      
40      /**
41       * Creates a new CharBuffer with an initial capacity of 32 characters.
42       */
43      public CharBuffer() {
44          this(32);
45      }
46      
47      /**
48       * Creates a new CharBuffer with an initial capacity 
49       * of <code>length</code> characters.
50       */
51      public CharBuffer(final int length) {
52          if (length == 0) {
53              throw new IllegalArgumentException("Can't create an empty CharBuffer");
54          }
55          this.c = new char[length];
56      }
57      
58      /**
59       * Empties the buffer. The capacity still remains the same, so no memory is freed.
60       */
61      public void clear() {
62          length = 0;
63      }
64      
65      /**
66       * Returns the number of characters in the buffer.
67       * @return the number of characters
68       */
69      public int length() {
70          return length;
71      }
72  
73      /**
74       * Returns the current capacity of the buffer.
75       * @return the maximum number of characters that can be stored in this buffer without
76       * resizing it.
77       */
78      public int capacity() {
79          return c.length;
80      }
81  
82      
83      /**
84       * Appends the contents of <code>cb</code> to the end of this CharBuffer.
85       * @param cb the CharBuffer to append or null
86       */
87      public void append(final CharBuffer cb) {
88          if (cb == null) {
89              return;
90          }
91          provideCapacity(length + cb.length);
92          System.arraycopy(cb.c, 0, c, length, cb.length);
93          length += cb.length;
94      }
95      
96      /**
97       * Appends <code>s</code> to the end of this CharBuffer.
98       * This method involves copying the new data once!
99       * @param s the String to append or null
100      */
101     public void append(final String s) {
102         if (s == null) {
103             return;
104         }
105         append(s.toCharArray());
106     }
107     
108     /**
109      * Appends <code>sb</code> to the end of this CharBuffer.
110      * This method involves copying the new data once!
111      * @param sb the StringBuffer to append or null
112      */
113     public void append(final StringBuffer sb) {
114         if (sb == null) {
115             return;
116         }
117         provideCapacity(length + sb.length());
118         sb.getChars(0, sb.length(), c, length);
119         length += sb.length();
120     }
121     
122     /**
123      * Appends <code>data</code> to the end of this CharBuffer.
124      * This method involves copying the new data once!
125      * @param data the char[] to append or null
126      */
127     public void append(final char[] data) {
128         if (data == null) {
129             return;
130         }
131         provideCapacity(length + data.length);
132         System.arraycopy(data, 0, c, length, data.length);
133         length += data.length;
134     }
135     
136     /**
137      * Appends a single character to the end of this CharBuffer.
138      * This method involves copying the new data once!
139      * @param data the char to append
140      */
141     public void append(final char data) {
142         provideCapacity(length + 1);
143         c[length] = data;
144         length++;
145     }
146     
147     /**
148      * Shrinks the capacity of the buffer to the current length if necessary.
149      * This method involves copying the data once!
150      */
151     public void shrink() {
152         if (c.length == length) {
153             return;
154         }
155         char[] newc = new char[length];
156         System.arraycopy(c, 0, newc, 0, length);
157         c = newc;
158     }
159 
160    /**
161     * Removes trailing whitespace.
162     */
163     public void trimTrailingWhitespace() {
164       while (length>0 && Character.isWhitespace(c[length-1])) {
165         length--;
166       }
167     }
168 
169     /**
170      * Returns the contents of the buffer as a char[]. The returned array may
171      * be the internal array of the buffer, so the caller must take care when
172      * modifying it.
173      * This method allows to avoid copying if the caller knows the exact capacity
174      * before.
175      * @return
176      */
177     public char[] getCharacters() {
178         if (c.length == length) {
179             return c;
180         }
181         char[] chars = new char[length];
182         System.arraycopy(c, 0, chars, 0, length);
183         return chars;
184     }
185 
186    /**
187     * Returns the character at the specified position.
188     */
189     public char charAt(int pos) {
190       return c[pos];
191    }
192 
193     /**
194      * Converts the contents of the buffer into a StringBuffer.
195      * This method involves copying the new data once!
196      * @return
197      */
198     public StringBuffer toStringBuffer() {
199         StringBuffer sb = new StringBuffer(length);
200         sb.append(c, 0, length);
201         return sb;
202     }
203     
204     /**
205      * Converts the contents of the buffer into a StringBuffer.
206      * This method involves copying the new data once!
207      * @return
208      */
209     public String toString() {
210         return new String(c, 0, length);
211     }
212     
213     /**
214      * Copies the data into a new array of at least <code>capacity</code> size.
215      * @param capacity
216      */
217     public void provideCapacity(final int capacity) {
218         if (c.length >= capacity) {
219             return;
220         }
221         int newcapacity = ((capacity*3)>>1) + 1;
222         char[] newc = new char[newcapacity];
223         System.arraycopy(c, 0, newc, 0, length);
224         c = newc;
225     }
226 }