001: /* WriterOutputStream.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Mon May 1 22:00:51 2006, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2006 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.io;
020:
021: import java.io.Writer;
022: import java.io.OutputStream;
023: import java.io.IOException;
024:
025: /**
026: * An output stream that is on top of a writer.
027: *
028: * @author tomyeh
029: */
030: public class WriterOutputStream extends OutputStream {
031: private final Writer _writer;
032: private final String _charset;
033: private final byte[] _bs; //used only with writer
034: private int _cnt, _type; //used only with writer
035:
036: /** Constructs an out stream with the specified encoding.
037: *
038: * @param charset the charset. If null, "UTF-8" is assumed.
039: */
040: public WriterOutputStream(Writer writer, String charset) {
041: if (writer == null)
042: throw new IllegalArgumentException("null");
043: _writer = writer;
044: _bs = new byte[3];
045: _charset = charset == null ? "UTF-8" : charset;
046: }
047:
048: /** Constructs an output stream assuming UTF-8 encoding.
049: */
050: public WriterOutputStream(Writer writer) {
051: this (writer, null);
052: }
053:
054: public void write(byte[] b) throws IOException {
055: _writer.write(new String(b, _charset));
056: }
057:
058: public void write(byte[] b, int off, int len) throws IOException {
059: _writer.write(new String(b, 0, b.length, _charset));
060: }
061:
062: public void write(int b) throws IOException {
063: if (_type != 0) {
064: if (!"UTF-8".equals(_charset) || (b & 0xc0) == 0x80) {
065: _bs[_cnt++] = (byte) b;
066: if (_cnt == _type) { //complete
067: _writer.write(new String(_bs, 0, _type, _charset));
068: _type = 0; //reset
069: }
070: return;
071: } else { //failed
072: for (int j = 0; j < _cnt; ++j)
073: _writer.write(_bs[j]);
074: _type = 0; //reset
075: }
076: } else {
077: if ("UTF-8".equals(_charset)) {
078: if ((b & 0xe0) == 0xc0 || (b & 0xf0) == 0xe0) {
079: _type = (b & 0xf0) == 0xe0 ? 3 : 2;
080: _bs[0] = (byte) b;
081: _cnt = 1;
082: return;
083: }
084: } else {
085: //assume two-bytes per char if 0x80 -- might fail.
086: if ((b & 0x80) != 0) {
087: _type = 2;
088: _bs[0] = (byte) b;
089: _cnt = 1;
090: return;
091: }
092: }
093: }
094: _writer.write(b);
095: }
096:
097: public void flush() throws IOException {
098: if (_type != 0) {
099: for (int j = 0; j < _cnt; ++j)
100: _writer.write(_bs[j]); //reset
101: _type = 0;
102: }
103: _writer.flush();
104: super .flush();
105: }
106:
107: public void close() throws IOException {
108: flush();
109: _writer.close();
110: super.close();
111: }
112: }
|