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