001: /*
002: * Created on Sep 15, 2005
003: */
004: package uk.org.ponder.streamutil.write;
005:
006: import java.io.IOException;
007: import java.io.OutputStream;
008: import java.nio.ByteBuffer;
009: import java.nio.CharBuffer;
010: import java.nio.charset.Charset;
011: import java.nio.charset.CharsetEncoder;
012:
013: import uk.org.ponder.streamutil.StreamCloseUtil;
014: import uk.org.ponder.util.UniversalRuntimeException;
015:
016: /**
017: * A combination of OutputStreamWriter and BufferedWriter - converts and outputs
018: * characters to an OutputStream with the minimum of fuss.
019: *
020: * @author Antranig Basman (antranig@caret.cam.ac.uk)
021: *
022: */
023:
024: public class OutputStreamPOS implements PrintOutputStream {
025: public int BUFFER_MAX = 1024;
026: private OutputStream os;
027: private static String DEFAULT_ENCODING = "UTF-8";
028: private CharBuffer charbuffer;
029: private char[] bufchars;
030: private CharsetEncoder ce;
031: private ByteBuffer bytebuffer;
032:
033: public OutputStreamPOS(OutputStream os) {
034: this (os, DEFAULT_ENCODING);
035: }
036:
037: public OutputStreamPOS(OutputStream os, String encoding) {
038: this .os = os;
039: Charset cs = Charset.forName(encoding);
040: ce = cs.newEncoder();
041: charbuffer = CharBuffer.allocate(BUFFER_MAX);
042: bufchars = charbuffer.array();
043: allocateByteBuffer(charbuffer.capacity());
044: }
045:
046: private void allocateByteBuffer(int chars) {
047: int reqsize = (int) (chars * ce.maxBytesPerChar());
048: if (bytebuffer == null || bytebuffer.capacity() < reqsize) {
049: bytebuffer = ByteBuffer.allocate(reqsize * 2);
050: }
051: }
052:
053: public void println(String toprint) {
054: print(toprint);
055: print("\n");
056: }
057:
058: public void flush() {
059: try {
060: flushInternal();
061: os.flush();
062: } catch (IOException e) {
063: throw UniversalRuntimeException.accumulate(e);
064: }
065: }
066:
067: public void close() {
068: flush();
069: StreamCloseUtil.closeOutputStream(os);
070: }
071:
072: private void flushInternal() {
073: bytebuffer.position(0);
074: charbuffer.limit(charbuffer.position());
075: charbuffer.position(0);
076: // deal with EOI and errors better at some point.
077: ce.encode(charbuffer, bytebuffer, true);
078: charbuffer.position(0);
079: charbuffer.limit(charbuffer.capacity());
080: try {
081: os.write(bytebuffer.array(), 0, bytebuffer.position());
082: } catch (IOException e) {
083: throw UniversalRuntimeException.accumulate(e);
084: }
085: }
086:
087: public PrintOutputStream print(String string) {
088: // byte[] bytes;
089: // try {
090: // bytes = string.getBytes(encoding);
091: // os.write(bytes);
092: // }
093: // catch (Exception e) {
094: // e.printStackTrace();
095: // }
096: if (string == null)
097: string = "null";
098: int stringlength = string.length();
099: int stringpos = 0;
100:
101: while (true) {
102: int remaining = charbuffer.remaining();
103: int towrite = stringlength - stringpos;
104: if (towrite > remaining) {
105: towrite = remaining;
106: }
107: int bufpos = charbuffer.position();
108: string.getChars(stringpos, stringpos + towrite, bufchars,
109: bufpos);
110: stringpos += towrite;
111: charbuffer.position(bufpos + towrite);
112: if (stringpos == stringlength)
113: break;
114: flushInternal();
115: }
116:
117: return this ;
118: }
119:
120: public void write(char[] storage, int offset, int size) {
121: while (true) {
122: int remaining = charbuffer.remaining();
123: int towrite = size;
124: if (towrite > remaining) {
125: towrite = remaining;
126: }
127: int bufpos = charbuffer.position();
128: charbuffer.put(storage, offset, towrite);
129: offset += towrite;
130: size -= towrite;
131: charbuffer.position(bufpos + towrite);
132: if (size == 0)
133: break;
134: flushInternal();
135: }
136: }
137:
138: public void println() {
139: print("\n");
140: }
141:
142: public void println(Object obj) {
143: print(obj.toString());
144: print("\n");
145: }
146:
147: }
|