001 package railo.commons.lang; 002 003 import java.io.IOException; 004 import java.io.OutputStream; 005 import java.io.UnsupportedEncodingException; 006 import java.io.Writer; 007 008 009 /** 010 * class to handle characters, similar to StringBuffer, but dont copy big blocks of char arrays. 011 */ 012 public class CharBuffer { 013 014 private final static int BLOCK_LENGTH = 1024; 015 private char buffer[]; 016 private int pos=0; 017 private int length=0; 018 private final Entity root=new Entity(null); 019 private Entity curr=root; 020 021 /** 022 * default constructor 023 */ 024 public CharBuffer() { 025 this(BLOCK_LENGTH); 026 } 027 028 /** 029 * constructor with size of the buffer 030 * @param size 031 */ 032 public CharBuffer(int size) { 033 buffer = new char[size]; 034 } 035 036 public void append(char c) { 037 append(new char[]{c}); 038 } 039 040 /** 041 * method to appennd a charr array to the buffer 042 * @param c char array to append 043 */ 044 public void append(char c[]) { 045 int maxlength=buffer.length-pos; 046 if(c.length<maxlength) { 047 System.arraycopy(c, 0, buffer, pos, c.length); 048 pos+=c.length; 049 } 050 else { 051 System.arraycopy(c, 0, buffer, pos, maxlength); 052 curr.next=new Entity(buffer); 053 curr=curr.next; 054 length+=buffer.length; 055 buffer=new char[(buffer.length>c.length-maxlength)?buffer.length:c.length-maxlength]; 056 if(c.length>maxlength) { 057 System.arraycopy(c, maxlength, buffer, 0, c.length-maxlength); 058 pos=c.length-maxlength; 059 } 060 else { 061 pos=0; 062 } 063 } 064 } 065 066 /** 067 * method to append a part of a char array 068 * @param c char array to get part from 069 * @param off start index on the char array 070 * @param len length of the sequenz to get from array 071 */ 072 public void append(char c[], int off, int len) { 073 int restLength=buffer.length-pos; 074 if(len<restLength) { 075 System.arraycopy(c, off, buffer, pos, len); 076 pos+=len; 077 } 078 else { 079 System.arraycopy(c, off, buffer, pos, restLength); 080 curr.next=new Entity(buffer); 081 curr=curr.next; 082 length+=buffer.length; 083 buffer=new char[(buffer.length>len-restLength)?buffer.length:len-restLength]; 084 085 System.arraycopy(c, off+restLength, buffer, 0, len-restLength); 086 pos=len-restLength; 087 088 } 089 } 090 091 /** 092 * Method to append a string to char buffer 093 * @param str String to append 094 */ 095 public void append(String str) { 096 if(str==null)return; 097 int restLength=buffer.length-pos; 098 if(str.length()<restLength) { 099 str.getChars(0,str.length(),buffer,pos); 100 pos+=str.length(); 101 } 102 else { 103 str.getChars(0,restLength,buffer,pos); 104 curr.next=new Entity(buffer); 105 curr=curr.next; 106 length+=buffer.length; 107 buffer=new char[(buffer.length>str.length()-restLength)?buffer.length:str.length()-restLength]; 108 109 str.getChars(restLength,str.length(),buffer,0); 110 pos=str.length()-restLength; 111 112 } 113 } 114 115 /** 116 * method to append a part of a String 117 * @param str string to get part from 118 * @param off start index on the string 119 * @param len length of the sequenz to get from string 120 */ 121 public void append(String str, int off, int len) { 122 int restLength=buffer.length-pos; 123 if(len<restLength) { 124 str.getChars(off,off+len,buffer,pos); 125 pos+=len; 126 } 127 else { 128 str.getChars(off,off+restLength,buffer,pos); 129 curr.next=new Entity(buffer); 130 curr=curr.next; 131 length+=buffer.length; 132 buffer=new char[(buffer.length>len-restLength)?buffer.length:len-restLength]; 133 134 str.getChars(off+restLength,off+len,buffer,0); 135 pos=len-restLength; 136 137 } 138 } 139 140 /** 141 * method to writeout content of the char buffer in a writer, 142 * this is faster than get char array with (toCharArray()) and write this 143 in writer. 144 * @param writer writer to write inside 145 * @throws IOException 146 */ 147 public void writeOut(Writer writer) throws IOException { 148 149 Entity e=root; 150 while(e.next!=null) { 151 e=e.next; 152 writer.write(e.data); 153 } 154 writer.write(buffer, 0, pos); 155 } 156 public void writeOut(OutputStream os, String charset) throws IOException { 157 Entity e=root; 158 while(e.next!=null) { 159 e=e.next; 160 os.write(new String(e.data).getBytes(charset)); 161 } 162 os.write(new String(buffer, 0, pos).getBytes(charset)); 163 } 164 165 166 /** 167 * return content of the Char Buffer as char array 168 * @return char array 169 */ 170 public char[] toCharArray() { 171 Entity e=root; 172 char[] chrs=new char[size()]; 173 int off=0; 174 while(e.next!=null) { 175 e=e.next; 176 System.arraycopy(e.data,0,chrs,off,e.data.length); 177 off+=e.data.length; 178 } 179 System.arraycopy(buffer,0,chrs,off,pos); 180 return chrs; 181 } 182 183 @Override 184 public String toString() { 185 return new String(toCharArray()); 186 } 187 188 /** 189 * clear the content of the buffer 190 */ 191 public void clear() { 192 if(size()==0)return; 193 buffer = new char[buffer.length]; 194 root.next=null; 195 pos = 0; 196 length=0; 197 curr=root; 198 } 199 200 /** 201 * @return returns the size of the content of the buffer 202 */ 203 public int size() { 204 return length+pos; 205 } 206 207 208 private class Entity { 209 private char[] data; 210 private Entity next; 211 212 private Entity(char[] data) { 213 this.data=data; 214 } 215 } 216 217 218 public byte[] getBytes(String characterEncoding) throws UnsupportedEncodingException { 219 220 221 return toString().getBytes(characterEncoding); 222 223 } 224 225 226 /*public static void main(String[] args) { 227 CharBuffer cb=new CharBuffer(3); 228 cb.append("12"); 229 cb.append("34"); 230 cb.append("5"); 231 cb.append("6"); 232 cb.append("7"); 233 cb.append("890-"); 234 cb.append("1234567890-1234567890-"); 235 236 cb=new CharBuffer(3); 237 cb.append("12",0,2); 238 cb.append("34",0,2); 239 cb.append("5",0,1); 240 cb.append("xxx6ggg",3,1); 241 cb.append("7zzz",0,1); 242 cb.append("890-",0,4); 243 cb.append("1234567890-1234567890-",0,22); 244 //System.out.println(cb+"->"+cb.size()); 245 246 247 cb=new CharBuffer(3); 248 cb.append(new char[]{'1','2'}); 249 cb.append(new char[]{'3','4'}); 250 cb.append(new char[]{'5'}); 251 cb.append(new char[]{'6'}); 252 cb.append(new char[]{'7'}); 253 cb.append(new char[]{'8','9','0','-'}); 254 cb.append(new char[]{'1','2','3','4','5','6','7','8','9','0','-','1','2','3','4','5','6','7','8','9','0','-'}); 255 System.out.println(cb+"->"+cb.size()); 256 257 258 259 cb=new CharBuffer(3); 260 cb.append(new char[]{'X','1','2','X'},1,2); 261 cb.append(new char[]{'3','4'},0,2); 262 cb.append(new char[]{'5'},0,1); 263 cb.append(new char[]{'6'},0,1); 264 cb.append(new char[]{'7'},0,1); 265 cb.append(new char[]{'8','9','0','-'},0,4); 266 cb.append(new char[]{'1','2','3','4','5','6','7','8','9','0','-','1','2','3','4','5','6','7','8','9','0','-'},0,22); 267 System.out.println(cb+"->"+cb.size()); 268 269 270 }*/ 271 }