KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > dyade > aaa > util > Pipe


1 /*
2  * Copyright (C) 2002 SCALAGENT
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17  * USA.
18  *
19  */

20 package fr.dyade.aaa.util;
21
22 import java.io.*;
23
24 import org.objectweb.util.monolog.api.BasicLevel;
25 import org.objectweb.util.monolog.api.Logger;
26
27 public class Pipe {
28   protected String JavaDoc name = null;
29
30   protected int size = 0;
31
32   /**
33    * The index of the position in the circular buffer at which the
34    * next byte of data will be stored when received from the connected
35    * piped output stream. <code>in&lt;0</code> implies the buffer is empty,
36    * <code>in==out</code> implies the buffer is full
37    */

38   protected int in = -1;
39
40   /**
41    * The index of the position in the circular buffer at which the next
42    * byte of data will be read by this piped input stream.
43    */

44   protected int out = 0;
45
46   private Logger logmon = null;
47   private long cpt1, cpt2;
48
49   public static final int DFLT_BUF_SIZE = 50;
50   public static final String JavaDoc DFLT_NAME = "noname";
51   public static final String JavaDoc DFLT_DIR = null;
52
53   /**
54    * The circular buffer into which incoming data is placed.
55    */

56   protected Object JavaDoc[] buffer = null;
57   
58   /**
59    * The index of the position in the file buffer at which the next piece
60    * of data will be read.
61    */

62   protected long fbufinptr = 0;
63   /**
64    * The index of the position in the file buffer at which the next piece
65    * of data will be write. <code>in&lt;0</code> implies the buffer is empty.
66    */

67   protected long fbufoutptr = -1;
68
69   protected RandomAccessFile fbufin = null;
70   protected RandomAccessFile fbufout = null;
71
72   /**
73    * Creates a <code>Pipe</code> with default size for memory buffer.
74    */

75   public Pipe() throws IOException {
76     this(DFLT_BUF_SIZE, DFLT_NAME, DFLT_DIR);
77   }
78
79   public final int getBufferSize() {
80     return size;
81   }
82
83   public final int getSizeInFile() {
84     if (fbufoutptr == -1)
85       return -1;
86     else
87       return (int) (fbufoutptr - fbufinptr);
88   }
89
90   /**
91    * Creates a <code>Pipe</code> with specified size for in memory buffer.
92    *
93    * @param size the size for in memory buffer.
94    */

95   public Pipe(int size, String JavaDoc name, String JavaDoc dir) throws IOException {
96     this.size = size;
97     buffer = new Object JavaDoc[size];
98
99     this.name = name;
100
101     File tmp = null;
102     if (dir == null)
103       tmp = File.createTempFile(name, "pipe");
104     else
105       tmp = File.createTempFile(name, "pipe", new File(dir));
106     tmp.deleteOnExit();
107     fbufin = new RandomAccessFile(tmp, "r");
108     fbufout = new RandomAccessFile(tmp, "rw");
109
110     logmon = Debug.getLogger("fr.dyade.aaa.util.Pipe.#" + name);
111   }
112
113   public synchronized void write(byte[] msg) throws IOException {
114     if ((fbufoutptr == -1) && (in != out)) {
115       // Neither the buffer is full, nor a buffer file is also in use.
116
// Put the element in the next square.
117
if (in < 0) {
118         in = 0;
119         out = 0;
120       }
121       buffer[in++] = (byte[]) msg;
122       if (in == size) in = 0;
123       notify();
124     } else {
125       // Either there is also a buffer file in use, or the buffer is full
126
// Append the element to the buffer file.
127
if (fbufoutptr == -1) {
128         fbufout.seek(0);
129         fbufoutptr = 0;
130       }
131       fbufout.writeInt(msg.length);
132       fbufout.write(msg);
133       fbufoutptr += 1;
134     }
135   }
136
137   public synchronized int read(Object JavaDoc[] buf) throws IOException {
138     while (in < 0) {
139       // The buffer is empty
140
if (fbufoutptr == -1) {
141         try {
142           wait();
143         } catch (InterruptedException JavaDoc ex) {
144           throw new java.io.InterruptedIOException JavaDoc();
145         }
146         continue;
147       } else {
148         in = 0;
149         out = 0;
150         int l;
151
152         /* fill in the circular buffer with data in file buffer */
153         while ((fbufinptr < fbufoutptr) && (in < size)) {
154           l = fbufin.readInt();
155           byte[] msg = new byte[l];
156           if (fbufin.read(msg) != l)
157             throw new IOException("buffer file corrupted");
158           buffer[in++] = msg;
159           fbufinptr += 1;
160         }
161         if (fbufinptr == fbufoutptr) {
162           // the file buffer is empty
163
fbufinptr = 0;
164           fbufoutptr = -1;
165           fbufout.setLength(0);
166           fbufin.seek(0);
167         }
168         if (in == size) in = 0;
169       }
170     }
171
172
173     int idx = 0;
174     // There is almost one element!
175
do {
176       buf[idx++] = buffer[out];
177       buffer[out] = null;
178       out += 1;
179       if (out >= size) out = 0;
180     } while ((out != in) && (idx < buf.length));
181
182     cpt1 += 1; cpt2 += idx;
183     if ((cpt1 %10000) == 0) {
184       if (logmon.isLoggable(BasicLevel.DEBUG)) {
185         logmon.log(BasicLevel.DEBUG,
186                    "Pipe.#" + name + ": " +
187                    cpt2 + '/' + cpt1 + '/' + in +'/' + out);
188       }
189     }
190
191     if (out == in) {
192       /* now empty */
193       in = -1;
194     }
195
196     return idx;
197   }
198 }
199
Popular Tags