KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xsocket > stream > StreamUtils


1 // $Id: IHandler.java 845 2007-01-29 08:41:35Z grro $
2
/*
3  * Copyright (c) xsocket.org, 2006 - 2007. All rights reserved.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Please refer to the LGPL license at: http://www.gnu.org/copyleft/lesser.txt
20  * The latest copy of this software may be found on http://www.xsocket.org/
21  */

22 package org.xsocket.stream;
23
24 import java.io.IOException JavaDoc;
25 import java.nio.BufferUnderflowException JavaDoc;
26
27 import org.xsocket.IDispatcher;
28 import org.xsocket.IWorkerPool;
29
30
31
32 /**
33  * utility class for stream based communication
34  *
35  * @author grro@xsocket.org
36  */

37 public final class StreamUtils {
38         
39     public static final String JavaDoc SERVER_TRHREAD_PREFIX = "xServer";
40     
41
42     private StreamUtils() { }
43
44     /**
45      * validate, based on a leading int length field, that enough data (getNumberOfAvailableBytes() >= length) is available. If not,
46      * an BufferUnderflowException will been thrown. The 4 bytes of the length field will be ignore by
47      * getting the available data size. Example:
48      * <pre>
49      * //client
50      * connection.setAutoflush(false); // avoid immediate write
51      * ...
52      * connection.markWritePosition(); // mark current position
53      * connection.write((int) 0); // write "emtpy" length field
54      *
55      * // write and count written size
56      * int written = connection.write(CMD_PUT);
57      * written += ...
58      *
59      * connection.resetToWriteMark(); // return to length field position
60      * connection.write(written); // and update it
61      * connection.flush(); // flush (marker will be removed implicit)
62      * ...
63      *
64      *
65      * // server
66      * class MyHandler implements IDataHandler {
67      * ...
68      * public boolean onData(INonBlockingConnection connection) throws IOException, BufferUnderflowException {
69      * int length = StreamUtils.validateSufficientDatasizeByIntLengthField(connection);
70      *
71      * // enough data (BufferUnderflowException hasn't been thrown)
72      * byte cmd = connection.readByte();
73      * ...
74      * }
75      * }
76      * </pre>
77      *
78      * @param connection the connection
79      * @return the length
80      * @throws IOException if an exception occurs
81      * @throws BufferUnderflowException if not enough data is available
82      */

83     public static int validateSufficientDatasizeByIntLengthField(INonBlockingConnection connection) throws IOException JavaDoc, BufferUnderflowException JavaDoc {
84
85         connection.resetToReadMark();
86         connection.markReadPosition();
87         
88         // check if enough data is available
89
int length = connection.readInt();
90         if (connection.getNumberOfAvailableBytes() < length) {
91             // ..no, throwing underflow exception
92
throw new BufferUnderflowException JavaDoc();
93     
94         } else {
95             // ...yes, remove mark
96
connection.removeReadMark();
97             return length;
98         }
99     }
100     
101     
102     /**
103      * starts the given server within a dedicated thread. This method blocks
104      * until the server is open.
105      *
106      * @param server the server to start
107      */

108     public static void start(IMultithreadedServer server) {
109         
110         // create and add startup listener
111
IMutlithreadedServerListener startupListener = new IMutlithreadedServerListener() {
112             
113             public void onInit() {
114                 synchronized (this) {
115                     notify();
116                 }
117             };
118             
119             public void onWorkerPoolUpdated(IWorkerPool oldWorkerPool,IWorkerPool newWorkerPool) { }
120             
121             public void onDispatcherRemoved(IDispatcher dispatcher) {};
122             
123             public void onDispatcherAdded(IDispatcher dispatcher) {};
124             
125             public void onDestroy() {};
126         };
127         server.addListener(startupListener);
128         
129         
130         // start server within a dedicated thread
131
Thread JavaDoc t = new Thread JavaDoc(server);
132         t.start();
133     
134         
135         // waiting until server is open by synchronizing with startup listener
136
if (!server.isOpen()) {
137             synchronized (startupListener) {
138                 try {
139                     startupListener.wait();
140                 } catch (InterruptedException JavaDoc ignore) { }
141             }
142         }
143
144         // update thread name
145
t.setName(SERVER_TRHREAD_PREFIX + ":" + server.getLocalPort());
146         
147         // remove the startup listener
148
server.removeListener(startupListener);
149     }
150 }
151
Popular Tags