1 29 30 package com.caucho.quercus.env; 31 32 import com.caucho.vfs.ReadStream; 33 import com.caucho.vfs.TempStream; 34 import com.caucho.vfs.WriteStream; 35 36 import java.io.IOException ; 37 import java.util.logging.Logger ; 38 39 42 public class OutputBuffer { 43 public static final int PHP_OUTPUT_HANDLER_START = 0; 44 public static final int PHP_OUTPUT_HANDLER_CONT = 1; 45 public static final int PHP_OUTPUT_HANDLER_END = 2; 46 47 private static final Logger log 48 = Logger.getLogger(OutputBuffer.class.getName()); 49 50 private int _state; 51 private boolean _haveFlushed; 52 private Callback _callback; 53 54 private final boolean _erase; 55 private final int _chunkSize; 56 private final int _level; 57 58 private final OutputBuffer _next; 59 60 private final TempStream _tempStream; 61 private final WriteStream _out; 62 63 private final Env _env; 64 65 OutputBuffer(OutputBuffer next, Env env, Callback callback, 66 int chunkSize, boolean erase) 67 { 68 _next = next; 69 70 if (_next != null) 71 _level = _next._level + 1; 72 else 73 _level = 1; 74 75 _erase = erase; 76 _chunkSize = chunkSize; 77 78 _env = env; 79 _callback = callback; 80 81 _tempStream = new TempStream(); 82 _out = new WriteStream(_tempStream); 83 _state = 1 << PHP_OUTPUT_HANDLER_START; 84 _haveFlushed = false; 85 } 86 87 90 public OutputBuffer getNext() 91 { 92 return _next; 93 } 94 95 98 public WriteStream getOut() 99 { 100 return _out; 101 } 102 103 106 public Value getContents() 107 { 108 try { 109 _out.flush(); 110 111 ReadStream rs = _tempStream.openRead(false); 112 BinaryBuilderValue bb = new BinaryBuilderValue(); 113 int ch; 114 115 while ((ch = rs.read()) >= 0) { 117 bb.appendByte(ch); 118 } 119 120 return bb; 121 } catch (IOException e) { 122 _env.error(e.toString(), e); 123 124 return BooleanValue.FALSE; 125 } 126 } 127 128 131 public long getLength() 132 { 133 try { 134 _out.flush(); 135 136 return (long)_tempStream.getLength(); 137 } catch (IOException e) { 138 _env.error(e.toString(), e); 139 140 return -1L; 141 } 142 } 143 144 147 public int getLevel() 148 { 149 return _level; 150 } 151 152 155 public boolean haveFlushed() 156 { 157 return _haveFlushed; 158 } 159 160 163 public boolean getEraseFlag() 164 { 165 return _erase; 172 } 173 174 177 public int getChunkSize() 178 { 179 return _chunkSize; 180 } 181 182 185 public void clean() 186 { 187 try { 188 _out.flush(); 189 190 _tempStream.clearWrite(); 191 } catch (IOException e) { 192 _env.error(e.toString(), e); 193 } 194 } 195 196 199 private void doFlush() 200 { 201 try { 202 _out.flush(); 203 204 ReadStream rs = _tempStream.openRead(true); 205 206 WriteStream out; 207 208 if (_next != null) 209 out = _next.getOut(); 210 else 211 out = _env.getOriginalOut(); 212 213 rs.writeToStream(out); 214 215 rs.close(); 216 } catch (IOException e) { 217 _env.error(e.toString(), e); 218 } 219 } 220 221 224 private void callCallback() 225 { 226 if (_callback != null) { 227 Value result = 228 _callback.call(_env, getContents(), LongValue.create(_state)); 229 230 if (result.isNull()) 232 return; 233 234 clean(); 235 236 try { 237 if (result instanceof BinaryValue) 238 _out.write(((BinaryValue) result).toBytes()); 239 else 240 _out.print(result.toString(_env).toString()); 241 } catch (IOException e) { 242 _env.error(e.toString(), e); 243 } 244 } 245 } 246 247 251 public void flush() 252 { 253 _state |= 1 << PHP_OUTPUT_HANDLER_CONT; 254 255 callCallback(); 256 257 _state &= ~(1 << PHP_OUTPUT_HANDLER_START); 259 _state &= ~(1 << PHP_OUTPUT_HANDLER_CONT); 260 261 doFlush(); 262 263 _haveFlushed = true; 264 } 265 266 269 public void close() 270 { 271 _state |= 1 << PHP_OUTPUT_HANDLER_END; 272 273 callCallback(); 274 275 _state = 0; 277 278 doFlush(); 279 } 280 281 284 public Callback getCallback() 285 { 286 return _callback; 287 } 288 289 292 public void setCallback(Callback callback) 293 { 294 _callback = callback; 295 } 296 } 297 298 | Popular Tags |