Quadcap Embeddable Server

com/quadcap/net/server/WorkerOutputStream.java

Go to the documentation of this file.
00001 package com.quadcap.net.server; 00002 00003 /* Copyright 1999 - 2003 Quadcap Software. All rights reserved. 00004 * 00005 * This software is distributed under the Quadcap Free Software License. 00006 * This software may be used or modified for any purpose, personal or 00007 * commercial. Open Source redistributions are permitted. Commercial 00008 * redistribution of larger works derived from, or works which bundle 00009 * this software requires a "Commercial Redistribution License"; see 00010 * http://www.quadcap.com/purchase. 00011 * 00012 * Redistributions qualify as "Open Source" under one of the following terms: 00013 * 00014 * Redistributions are made at no charge beyond the reasonable cost of 00015 * materials and delivery. 00016 * 00017 * Redistributions are accompanied by a copy of the Source Code or by an 00018 * irrevocable offer to provide a copy of the Source Code for up to three 00019 * years at the cost of materials and delivery. Such redistributions 00020 * must allow further use, modification, and redistribution of the Source 00021 * Code under substantially the same terms as this license. 00022 * 00023 * Redistributions of source code must retain the copyright notices as they 00024 * appear in each source code file, these license terms, and the 00025 * disclaimer/limitation of liability set forth as paragraph 6 below. 00026 * 00027 * Redistributions in binary form must reproduce this Copyright Notice, 00028 * these license terms, and the disclaimer/limitation of liability set 00029 * forth as paragraph 6 below, in the documentation and/or other materials 00030 * provided with the distribution. 00031 * 00032 * The Software is provided on an "AS IS" basis. No warranty is 00033 * provided that the Software is free of defects, or fit for a 00034 * particular purpose. 00035 * 00036 * Limitation of Liability. Quadcap Software shall not be liable 00037 * for any damages suffered by the Licensee or any third party resulting 00038 * from use of the Software. 00039 */ 00040 00041 import java.io.FileOutputStream; 00042 import java.io.IOException; 00043 import java.io.OutputStream; 00044 00045 import com.quadcap.util.Debug; 00046 00047 /** 00048 * An efficient worker output stream, which is <B>NOT</B> destroyed after 00049 * each session, to reduce allocation overhead. This class performs 00050 * all necessary buffering of the Socket OutputStream, so no extra 00051 * "buffer stream" classes are needed. 00052 * 00053 * @author Stan Bailes 00054 */ 00055 public final class WorkerOutputStream extends OutputStream { 00056 static final int MAX = 4096; 00057 byte[] buf = new byte[MAX]; 00058 byte[] temp = new byte[16]; 00059 int pos = 0; 00060 OutputStream out; 00061 00062 //#ifdef DEBUG 00063 static boolean doTrace = false; 00064 FileOutputStream log; 00065 //#endif 00066 00067 public WorkerOutputStream(FileOutputStream log) { 00068 //#ifdef DEBUG 00069 doTrace = (log != null); 00070 this.log = log; 00071 //#endif 00072 } 00073 00074 public final void reset(OutputStream out) throws IOException { 00075 this.out = out; 00076 this.pos = 0; 00077 //#ifdef DEBUG 00078 if (doTrace) { 00079 log.write(("RESET " + Thread.currentThread().getName() + 00080 "\r\n").getBytes()); 00081 } 00082 //#endif 00083 } 00084 00085 public final void write(int c) throws IOException { 00086 if (pos >= MAX) { 00087 owrite(buf, 0, MAX); 00088 } 00089 buf[pos++] = (byte)c; 00090 } 00091 00092 final void owrite(byte[] b, int off, int len) throws IOException { 00093 out.write(b, off, len); 00094 pos = 0; 00095 //#ifdef DEBUG 00096 if (doTrace) { 00097 log.write("WRITE\r\n".getBytes()); 00098 log.write(b, off, len); 00099 } 00100 //#endif 00101 } 00102 00103 public final void write(String s) throws IOException { 00104 int len = s.length(); 00105 int off = 0; 00106 while (len + pos >= MAX) { 00107 int slen = MAX - pos; 00108 s.getBytes(off, off + slen, buf, pos); 00109 owrite(buf, 0, MAX); 00110 off += slen; 00111 len -= slen; 00112 pos = 0; 00113 } 00114 if (len > 0) { 00115 s.getBytes(off, len, buf, pos); 00116 pos += len; 00117 } 00118 } 00119 00120 public final void write(byte[] b, int off, int len) throws IOException { 00121 final int npos = pos + len; 00122 if (npos >= MAX) { 00123 if (pos == 0) { 00124 owrite(b, off, len); 00125 } else { 00126 final int slen = MAX - pos; 00127 System.arraycopy(b, off, buf, pos, slen); 00128 owrite(buf, 0, MAX); 00129 len -= slen; 00130 if (len < MAX) { 00131 System.arraycopy(b, off + slen, buf, 0, len); 00132 pos = len; 00133 } else { 00134 pos = 0; 00135 owrite(b, off + slen, len); 00136 } 00137 } 00138 } else { 00139 System.arraycopy(b, off, buf, pos, len); 00140 pos = npos; 00141 } 00142 } 00143 00144 public final void write(byte[] b) throws IOException { 00145 write(b, 0, b.length); 00146 } 00147 00148 public final void flush() throws IOException { 00149 if (pos > 0) { 00150 owrite(buf, 0, pos); 00151 pos = 0; 00152 } 00153 out.flush(); 00154 } 00155 00156 static final byte[] digits = "0123456789".getBytes(); 00157 00158 public final void writeInt(int x) throws IOException { 00159 int p = 0; 00160 while (x > 0) { 00161 temp[p++] = digits[x % 10]; 00162 x /= 10; 00163 } 00164 if (p == 0) temp[p++] = (byte)'0'; 00165 if (pos + p < MAX) { 00166 while (p > 0) buf[pos++] = temp[--p]; 00167 } else { 00168 while (p > 0) write(temp[--p]); 00169 } 00170 } 00171 00172 public final void close() throws IOException { 00173 flush(); 00174 out.close(); 00175 //#ifdef DEBUG 00176 if (doTrace) log.write("CLOSE\r\n".getBytes()); 00177 //#endif 00178 } 00179 }