001 /*
002 * ObjectWriter.java
003 *
004 * Copyright (c) 1995-2010, The University of Sheffield. See the file
005 * COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
006 *
007 * This file is part of GATE (see http://gate.ac.uk/), and is free
008 * software, licenced under the GNU Library General Public License,
009 * Version 2, June 1991 (in the distribution as file licence.html,
010 * and also available at http://gate.ac.uk/gate/licence.html).
011 *
012 * Valentin Tablan 21 Feb 2000
013 *
014 * $Id: ObjectWriter.java 12006 2009-12-01 17:24:28Z thomas_heitz $
015 */
016
017 package gate.util;
018
019 import java.io.*;
020 import java.util.Iterator;
021 import java.util.LinkedList;
022
023 /** Writes an object to an PipedOutputStream wich can be connected to a
024 * PipedInputStream.
025 * Before writting the object it also writes it in a buffer and finds
026 * out its size so it can be reported via getSize method.
027 * All read/writes occur in separate threads to avoid a deadlock.
028 */
029 public class ObjectWriter extends Thread {
030
031 /** Debug flag */
032 private static final boolean DEBUG = false;
033
034 public ObjectWriter(Object obj) throws IOException {
035 size = 0;
036 Writer writer = new Writer(obj);
037 InputStream is = writer.getInputStream();
038 writer.start();
039 boolean over = false;
040 buffer = new LinkedList();
041
042 //how much space is available in lastBuff
043 int space = buffSize;
044
045 //where to write in lastBuff
046 int writeOffset = 0;
047 byte lastBuff[] = new byte[buffSize];
048
049 while (!over) {
050 int read = is.read(lastBuff, writeOffset, space);
051 if(read == -1) {
052 lastOffset = writeOffset;
053 buffer.addLast(lastBuff);
054 over = true;
055 } else {
056 space-= read;
057 size+=read;
058 if(space == 0) {
059 // no more space; we need a new buffer
060 buffer.addLast(lastBuff);
061 space = buffSize;
062 writeOffset = 0;
063 lastBuff = new byte[buffSize];
064 } else {
065 // current buffer not full yet
066 writeOffset+=read;
067 }
068 }
069 };// while(!over)
070
071 // will be used to write the data
072 outputStream = new PipedOutputStream();
073
074 // will be returned for objects that want to read the object
075 inputStream = new PipedInputStream(outputStream);
076 }
077
078 /**
079 * Returns a PipedInputStream from which the object given as parameter for
080 * the constructor can be read.
081 *
082 * @return a PipedInputStream connected to PipedOutputStream which writes
083 * the object which this ObjectWriter was built for.
084 */
085 public InputStream getInputStream() {
086 return inputStream;
087 }
088
089 /**
090 * Obtains the object size.
091 *
092 * @return the size of the object recieved as parameter for the constructor.
093 */
094 public int getSize() {
095 return size;
096 }
097
098 /** Writes all the buffers to the output stream
099 */
100 public void run() {
101 try{
102 Iterator buffIter = buffer.iterator();
103 while(buffIter.hasNext()){
104 byte currentBuff[] = (byte[])buffIter.next();
105 if(buffIter.hasNext()) {
106 // is not the last buffer
107 outputStream.write(currentBuff,0,buffSize);
108 } else {
109 // is the last buffer
110 // currentBuff[lastOffset] = '\u001a';
111 outputStream.write(currentBuff,0,lastOffset);
112 }
113 }// while(buffIter.hasNext())
114
115 outputStream.flush();
116 outputStream.close();
117 } catch(IOException ioe) {
118 throw new RuntimeException(ioe.toString());
119 // ioe.printStackTrace(Err.getPrintWriter());
120 }
121 }
122
123
124 /** I need a thread to write the object so I can read it in an buffer
125 * After that I know the size ana I can write it to the output stream
126 * after I report the size.
127 */
128 private class Writer extends Thread {
129 public Writer(Object _obj){
130 _object = _obj;
131 _outputStream = new PipedOutputStream();
132
133 try {
134 _inputStream = new PipedInputStream(_outputStream);
135 } catch(IOException ioe) {
136 ioe.printStackTrace(Err.getPrintWriter());
137 }
138 }
139
140 public InputStream getInputStream(){
141 return _inputStream;
142 }
143
144 /**
145 * Describe 'run' method here.
146 */
147 public void run(){
148 try {
149 ObjectOutputStream _oos = new ObjectOutputStream(_outputStream);
150 _oos.writeObject(_object);
151 _oos.close();
152 } catch(IOException ioe) {
153 ioe.printStackTrace(Err.getPrintWriter());
154 }
155 }
156
157 private Object _object;
158 private InputStream _inputStream;
159 private PipedOutputStream _outputStream;
160
161 }
162
163 private Object object;
164
165 private InputStream inputStream ;
166
167 private PipedOutputStream outputStream;
168
169 private int size;
170
171 private int lastOffset;
172
173 private LinkedList buffer;
174
175 private int buffSize = 1024;
176
177 } // class ObjectWriter
|