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 ist 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 /** 184 * return the content of the buffer as string 185 * @see java.lang.Object#toString() 186 */ 187 public String toString() { 188 return new String(toCharArray()); 189 } 190 191 /** 192 * clear the content of the buffer 193 */ 194 public void clear() { 195 if(size()==0)return; 196 buffer = new char[buffer.length]; 197 root.next=null; 198 pos = 0; 199 length=0; 200 curr=root; 201 } 202 203 /** 204 * @return returns the size of the content of the buffer 205 */ 206 public int size() { 207 return length+pos; 208 } 209 210 211 private class Entity { 212 private char[] data; 213 private Entity next; 214 215 private Entity(char[] data) { 216 this.data=data; 217 } 218 } 219 220 221 public byte[] getBytes(String characterEncoding) throws UnsupportedEncodingException { 222 223 224 return toString().getBytes(characterEncoding); 225 226 } 227 228 229 /*public static void main(String[] args) { 230 CharBuffer cb=new CharBuffer(3); 231 cb.append("12"); 232 cb.append("34"); 233 cb.append("5"); 234 cb.append("6"); 235 cb.append("7"); 236 cb.append("890-"); 237 cb.append("1234567890-1234567890-"); 238 239 cb=new CharBuffer(3); 240 cb.append("12",0,2); 241 cb.append("34",0,2); 242 cb.append("5",0,1); 243 cb.append("xxx6ggg",3,1); 244 cb.append("7zzz",0,1); 245 cb.append("890-",0,4); 246 cb.append("1234567890-1234567890-",0,22); 247 //System.out.println(cb+"->"+cb.size()); 248 249 250 cb=new CharBuffer(3); 251 cb.append(new char[]{'1','2'}); 252 cb.append(new char[]{'3','4'}); 253 cb.append(new char[]{'5'}); 254 cb.append(new char[]{'6'}); 255 cb.append(new char[]{'7'}); 256 cb.append(new char[]{'8','9','0','-'}); 257 cb.append(new char[]{'1','2','3','4','5','6','7','8','9','0','-','1','2','3','4','5','6','7','8','9','0','-'}); 258 System.out.println(cb+"->"+cb.size()); 259 260 261 262 cb=new CharBuffer(3); 263 cb.append(new char[]{'X','1','2','X'},1,2); 264 cb.append(new char[]{'3','4'},0,2); 265 cb.append(new char[]{'5'},0,1); 266 cb.append(new char[]{'6'},0,1); 267 cb.append(new char[]{'7'},0,1); 268 cb.append(new char[]{'8','9','0','-'},0,4); 269 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); 270 System.out.println(cb+"->"+cb.size()); 271 272 273 }*/ 274 }