| ObjectWriter.java |
1 /*
2 * ObjectWriter.java
3 *
4 * Copyright (c) 1998-2004, The University of Sheffield.
5 *
6 * This file is part of GATE (see http://gate.ac.uk/), and is free
7 * software, licenced under the GNU Library General Public License,
8 * Version 2, June 1991 (in the distribution as file licence.html,
9 * and also available at http://gate.ac.uk/gate/licence.html).
10 *
11 * Valentin Tablan 21 Feb 2000
12 *
13 * $Id: ObjectWriter.java,v 1.13 2004/07/21 17:10:09 akshay Exp $
14 */
15
16 package gate.util;
17
18 import java.io.*;
19 import java.util.Iterator;
20 import java.util.LinkedList;
21
22 /** Writes an object to an PipedOutputStream wich can be connected to a
23 * PipedInputStream.
24 * Before writting the object it also writes it in a buffer and finds
25 * out its size so it can be reported via getSize method.
26 * All read/writes occur in separate threads to avoid a deadlock.
27 */
28 public class ObjectWriter extends Thread {
29
30 /** Debug flag */
31 private static final boolean DEBUG = false;
32
33 public ObjectWriter(Object obj) throws IOException {
34 size = 0;
35 Writer writer = new Writer(obj);
36 InputStream is = writer.getInputStream();
37 writer.start();
38 boolean over = false;
39 buffer = new LinkedList();
40
41 //how much space is available in lastBuff
42 int space = buffSize;
43
44 //where to write in lastBuff
45 int writeOffset = 0;
46 byte lastBuff[] = new byte[buffSize];
47
48 while (!over) {
49 int read = is.read(lastBuff, writeOffset, space);
50 if(read == -1) {
51 lastOffset = writeOffset;
52 buffer.addLast(lastBuff);
53 over = true;
54 } else {
55 space-= read;
56 size+=read;
57 if(space == 0) {
58 // no more space; we need a new buffer
59 buffer.addLast(lastBuff);
60 space = buffSize;
61 writeOffset = 0;
62 lastBuff = new byte[buffSize];
63 } else {
64 // current buffer not full yet
65 writeOffset+=read;
66 }
67 }
68 };// while(!over)
69
70 // will be used to write the data
71 outputStream = new PipedOutputStream();
72
73 // will be returned for objects that want to read the object
74 inputStream = new PipedInputStream(outputStream);
75 }
76
77 /**
78 * Returns a PipedInputStream from which the object given as parameter for
79 * the constructor can be read.
80 *
81 * @return a PipedInputStream connected to PipedOutputStream which writes
82 * the object which this ObjectWriter was built for.
83 */
84 public InputStream getInputStream() {
85 return inputStream;
86 }
87
88 /**
89 * Obtains the object size.
90 *
91 * @return the size of the object recieved as parameter for the constructor.
92 */
93 public int getSize() {
94 return size;
95 }
96
97 /** Writes all the buffers to the output stream
98 */
99 public void run() {
100 try{
101 Iterator buffIter = buffer.iterator();
102 while(buffIter.hasNext()){
103 byte currentBuff[] = (byte[])buffIter.next();
104 if(buffIter.hasNext()) {
105 // is not the last buffer
106 outputStream.write(currentBuff,0,buffSize);
107 } else {
108 // is the last buffer
109 // currentBuff[lastOffset] = '\u001a';
110 outputStream.write(currentBuff,0,lastOffset);
111 }
112 }// while(buffIter.hasNext())
113
114 outputStream.flush();
115 outputStream.close();
116 } catch(IOException ioe) {
117 throw new RuntimeException(ioe.toString());
118 // ioe.printStackTrace(Err.getPrintWriter());
119 }
120 }
121
122
123 /** I need a thread to write the object so I can read it in an buffer
124 * After that I know the size ana I can write it to the output stream
125 * after I report the size.
126 */
127 private class Writer extends Thread {
128 public Writer(Object _obj){
129 _object = _obj;
130 _outputStream = new PipedOutputStream();
131
132 try {
133 _inputStream = new PipedInputStream(_outputStream);
134 } catch(IOException ioe) {
135 ioe.printStackTrace(Err.getPrintWriter());
136 }
137 }
138
139 public InputStream getInputStream(){
140 return _inputStream;
141 }
142
143 /**
144 * Describe 'run' method here.
145 */
146 public void run(){
147 try {
148 ObjectOutputStream _oos = new ObjectOutputStream(_outputStream);
149 _oos.writeObject(_object);
150 _oos.close();
151 } catch(IOException ioe) {
152 ioe.printStackTrace(Err.getPrintWriter());
153 }
154 }
155
156 private Object _object;
157 private InputStream _inputStream;
158 private PipedOutputStream _outputStream;
159
160 }
161
162 private Object object;
163
164 private InputStream inputStream ;
165
166 private PipedOutputStream outputStream;
167
168 private int size;
169
170 private int lastOffset;
171
172 private LinkedList buffer;
173
174 private int buffSize = 1024;
175
176 } // class ObjectWriter
177