package railo.commons.lang; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; /** * class to handle characters, similar to StringBuffer, but dont copy big blocks of char arrays. */ public class ByteBuffer { private final static int BLOCK_LENGTH = 1024; private byte buffer[]; private int pos=0; private int length=0; private final Entity root=new Entity(null); private Entity curr=root; private final String charset; /** * default constructor */ public ByteBuffer(String charset) { this(charset,BLOCK_LENGTH); } /** * constructor with size of the buffer * @param size */ public ByteBuffer(String charset,int size) { buffer = new byte[size]; this.charset=charset; } public void append(char c) throws IOException { append(new String(new char[]{c})); } /** * method to appennd a charr array to the buffer * @param c char array to append * @throws IOException */ public void append(char c[]) throws IOException { append(new String(c)); } public void append(byte c[]) { int maxlength=buffer.length-pos; if(c.length<maxlength) { System.arraycopy(c, 0, buffer, pos, c.length); pos+=c.length; } else { System.arraycopy(c, 0, buffer, pos, maxlength); curr.next=new Entity(buffer); curr=curr.next; length+=buffer.length; buffer=new byte[(buffer.length>c.length-maxlength)?buffer.length:c.length-maxlength]; if(c.length>maxlength) { System.arraycopy(c, maxlength, buffer, 0, c.length-maxlength); pos=c.length-maxlength; } else { pos=0; } } } /** * method to append a part of a char array * @param c char array to get part from * @param off start index on the char array * @param len length of the sequenz to get from array * @throws IOException */ public void append(char c[], int off, int len) throws IOException { append(new String(c,off,len)); } /** * Method to append a string to char buffer * @param str String to append * @throws IOException */ public void append(String str) throws IOException { append(str.getBytes(charset)); } /** * method to append a part of a String * @param str string to get part from * @param off start index on the string * @param len length of the sequenz to get from string * @throws IOException */ public void append(String str, int off, int len) throws IOException { append(str.substring(off, off+len)); } /** * method to writeout content of the char buffer in a writer, * this is faster than get char array with (toCharArray()) and write this in writer. * @param writer writer to write inside * @throws IOException */ public void writeOut(OutputStream os) throws IOException { Entity e=root; while(e.next!=null) { e=e.next; os.write(e.data); } os.write(buffer,0,pos); } @Override public String toString() { try { return new String(getBytes(),charset); } catch (UnsupportedEncodingException e) { return new String(getBytes()); } } /** * clear the content of the buffer */ public void clear() { if(size()==0)return; buffer = new byte[buffer.length]; root.next=null; pos = 0; length=0; curr=root; } /** * @return returns the size of the content of the buffer */ public int size() { return length+pos; } private class Entity { private byte[] data; private Entity next; private Entity(byte[] data) { this.data=data; } } public byte[] getBytes() { ByteArrayOutputStream baos=new ByteArrayOutputStream(); try { writeOut(baos); } catch (IOException e) {} return baos.toByteArray(); } public static void main(String[] args) throws IOException { ByteBuffer cb=new ByteBuffer("utf-8",3); cb.append("12"); cb.append("34"); cb.append("5"); cb.append("6"); cb.append("7"); cb.append("890-"); cb.append("1234567890-1234567890-"); System.out.println(cb+"->"+cb.size()); cb=new ByteBuffer("utf-8",3); cb.append("12",0,2); cb.append("34",0,2); cb.append("5",0,1); cb.append("xxx6ggg",3,1); cb.append("7zzz",0,1); cb.append("890-",0,4); cb.append("1234567890-1234567890-",0,22); System.out.println(cb+"->"+cb.size()); cb=new ByteBuffer("utf-8",3); cb.append(new char[]{'1','2'}); cb.append(new char[]{'3','4'}); cb.append(new char[]{'5'}); cb.append(new char[]{'6'}); cb.append(new char[]{'7'}); cb.append(new char[]{'8','9','0','-'}); cb.append(new char[]{'1','2','3','4','5','6','7','8','9','0','-','1','2','3','4','5','6','7','8','9','0','-'}); System.out.println(cb+"->"+cb.size()); cb=new ByteBuffer("utf-8",3); cb.append(new char[]{'X','1','2','X'},1,2); cb.append(new char[]{'3','4'},0,2); cb.append(new char[]{'5'},0,1); cb.append(new char[]{'6'},0,1); cb.append(new char[]{'7'},0,1); cb.append(new char[]{'8','9','0','-'},0,4); 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); System.out.println(cb+"->"+cb.size()); cb=new ByteBuffer("utf-8",3); cb.append(new char[]{'�'}); System.out.println(cb+"->"+cb.size()); } }