1 28 29 package com.caucho.vfs; 30 31 import java.io.CharConversionException ; 32 import java.io.EOFException ; 33 import java.io.IOException ; 34 import java.io.OutputStreamWriter ; 35 import java.io.Reader ; 36 import java.io.Writer ; 37 38 public class ReaderWriterStream extends StreamImpl { 39 private static NullPath nullPath; 40 41 private Reader is; 42 private Writer os; 43 private boolean flushOnNewline; 44 private boolean closeChildOnClose = true; 45 46 private int peek1; 47 private int peek2; 48 49 public ReaderWriterStream(Reader is, Writer os) 50 { 51 init(is, os); 52 if (nullPath == null) 53 nullPath = new NullPath("stream"); 54 setPath(nullPath); 55 } 56 57 public ReaderWriterStream(Reader is, Writer os, Path path) 58 { 59 init(is, os); 60 setPath(path); 61 } 62 63 public void init(Reader is, Writer os) 64 { 65 this.is = is; 66 this.os = os; 67 setPath(nullPath); 68 peek1 = -1; 69 peek2 = -1; 70 } 71 72 public String getEncoding() 73 { 74 if (os instanceof OutputStreamWriter ) 75 return Encoding.getMimeName(((OutputStreamWriter ) os).getEncoding()); 76 else 77 return null; 78 } 79 80 public boolean canRead() 81 { 82 return is != null; 83 } 84 85 public int read(byte []buf, int offset, int length) throws IOException 86 { 87 if (is == null) 88 return -1; 89 90 for (int i = 0; i < length; i++) { 91 int ch; 92 if (peek1 >= 0) { 93 buf[offset++] = (byte) peek1; 94 peek1 = peek2; 95 peek2 = -1; 96 } 97 else if ((ch = is.read()) < 0) { 98 return i == 0 ? -1 : i; 99 } 100 else if (ch < 0x80) { 101 buf[offset++] = (byte) ch; 102 } 103 else if (ch < 0x800) { 104 buf[offset++] = (byte) (0xc0 + (ch >> 6)); 105 peek1 = 0x80 + (ch & 0x3f); 106 } 107 else { 108 buf[offset++] = (byte) (0xe0 + (ch >> 12)); 109 peek1 = 0x80 + ((ch >> 6) & 0x3f); 110 peek2 = 0x80 + (ch & 0x3f); 111 } 112 } 113 114 return length; 115 } 116 117 public boolean canWrite() 118 { 119 return os != null; 120 } 121 122 public boolean getFlushOnNewline() 123 { 124 return flushOnNewline; 125 } 126 127 public void setFlushOnNewline(boolean value) 128 { 129 flushOnNewline = value; 130 } 131 132 140 public void write(byte []buf, int offset, int length, boolean isEnd) 141 throws IOException 142 { 143 int end = offset + length; 144 while (offset < end) { 145 int ch1 = buf[offset++] & 0xff; 146 147 if (ch1 < 0x80) 148 os.write(ch1); 149 else if ((ch1 & 0xe0) == 0xc0) { 150 if (offset >= end) 151 throw new EOFException ("unexpected end of file in utf8 character"); 152 153 int ch2 = buf[offset++] & 0xff; 154 if ((ch2 & 0xc0) != 0x80) 155 throw new CharConversionException ("illegal utf8 encoding"); 156 157 os.write(((ch1 & 0x1f) << 6) + (ch2 & 0x3f)); 158 } 159 else if ((ch1 & 0xf0) == 0xe0) { 160 if (offset + 1 >= end) 161 throw new EOFException ("unexpected end of file in utf8 character"); 162 163 int ch2 = buf[offset++] & 0xff; 164 int ch3 = buf[offset++] & 0xff; 165 166 if ((ch2 & 0xc0) != 0x80) 167 throw new CharConversionException ("illegal utf8 encoding"); 168 169 if ((ch3 & 0xc0) != 0x80) 170 throw new CharConversionException ("illegal utf8 encoding"); 171 172 os.write(((ch1 & 0x1f) << 12) + ((ch2 & 0x3f) << 6) + (ch3 & 0x3f)); 173 } 174 else 175 throw new CharConversionException ("illegal utf8 encoding at (" + 176 (int) ch1 + ")"); 177 } 178 } 179 180 public void flush() throws IOException 181 { 182 if (os != null) 183 os.flush(); 184 } 185 186 public void setCloseChildOnClose(boolean close) 187 { 188 closeChildOnClose = close; 189 } 190 191 public void close() throws IOException 192 { 193 if (os != null && closeChildOnClose) { 194 os.close(); 195 os = null; 196 } 197 198 if (is != null && closeChildOnClose) { 199 is.close(); 200 is = null; 201 } 202 } 203 } 204 | Popular Tags |