1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package uk.ac.rdg.resc.jstyx.server;
30
31 import org.apache.log4j.Logger;
32
33 import org.apache.mina.common.ByteBuffer;
34
35 import uk.ac.rdg.resc.jstyx.StyxUtils;
36 import uk.ac.rdg.resc.jstyx.StyxException;
37 import uk.ac.rdg.resc.jstyx.types.ULong;
38
39 /***
40 * File whose underlying data are stored as a ByteBuffer in memory. This buffer
41 * can grow to arbitrary size.
42 *
43 * @author Jon Blower
44 * $Revision: 601 $
45 * $Date: 2006-03-20 17:51:50 +0000 (Mon, 20 Mar 2006) $
46 * $Log$
47 * Revision 1.20 2006/03/20 17:51:50 jonblower
48 * Adding authentication to base JStyx system
49 *
50 * Revision 1.19 2005/09/08 07:08:59 jonblower
51 * Removed "String user" from list of parameters to StyxFile.write()
52 *
53 * Revision 1.18 2005/09/02 16:51:20 jonblower
54 * Fixed bug with ByteBuffers being released prematurely and changed to use autoExpanding ByteBuffers
55 *
56 * Revision 1.17 2005/09/01 07:50:22 jonblower
57 * Trying to fix bug with ByteBuffers being released (can't read from InMemoryFile)
58 *
59 * Revision 1.16 2005/08/30 16:29:00 jonblower
60 * Added processAndReplyRead() helper functions to StyxFile
61 *
62 * Revision 1.13 2005/06/10 07:53:12 jonblower
63 * Changed SGS namespace: removed "inurl" and subsumed functionality into "stdin"
64 *
65 * Revision 1.12 2005/04/28 08:11:15 jonblower
66 * Modified permissions handling in documentation directory of SGS
67 *
68 * Revision 1.10 2005/04/27 16:11:43 jonblower
69 * Added capability to add documentation files to SGS namespace
70 *
71 * Revision 1.9 2005/04/26 07:46:11 jonblower
72 * Continuing to improve setting of parameters in Styx Grid Services
73 *
74 * Revision 1.8 2005/03/24 15:11:07 jonblower
75 * Changed so that underlying ByteBuffer is allocated on the first write to the file
76 *
77 * Revision 1.7 2005/03/24 13:07:09 jonblower
78 * Added code to prevent the file growing to larger than a specified size
79 *
80 * Revision 1.6 2005/03/24 12:55:14 jonblower
81 * Changed to use ByteBuffer as backing store
82 *
83 * Revision 1.5 2005/03/24 09:48:31 jonblower
84 * Changed 'count' from long to int throughout for reading and writing
85 *
86 * Revision 1.4 2005/03/16 17:56:23 jonblower
87 * Replaced use of java.nio.ByteBuffer with MINA's ByteBuffer to minimise copying of buffers
88 *
89 * Revision 1.3 2005/03/11 14:02:16 jonblower
90 * Merged MINA-Test_20059309 into main line of development
91 *
92 * Revision 1.2.2.1 2005/03/10 20:55:38 jonblower
93 * Removed references to Netty
94 *
95 * Revision 1.2 2005/03/01 13:47:43 jonblower
96 * Changed default user and group to 'user' and 'group'
97 *
98 * Revision 1.1.1.1 2005/02/16 18:58:31 jonblower
99 * Initial import
100 *
101 */
102 public class InMemoryFile extends StyxFile
103 {
104
105 private static final Logger log = Logger.getLogger(InMemoryFile.class);
106
107 /***
108 * The org.apache.mina.common.ByteBuffer that holds the data exposed by this file.
109 * The first byte of readable data is always at position zero and the number
110 * of valid bytes in the buffer is its limit
111 */
112 protected ByteBuffer buf;
113
114 /***
115 * Creates a new instance of InMemoryFile
116 */
117 public InMemoryFile(String name, String userID, String groupID,
118 int permissions, boolean isAppendOnly, boolean isExclusive)
119 throws StyxException
120 {
121 super(name, userID, groupID, permissions, isAppendOnly, isExclusive);
122 }
123
124 public InMemoryFile(String name, int permissions,
125 boolean isAppendOnly, boolean isExclusive)
126 throws StyxException
127 {
128 this(name, "user", "group", permissions, isAppendOnly, isExclusive);
129 }
130
131 public InMemoryFile(String name, int permissions)
132 throws StyxException
133 {
134 this(name, permissions, false, false);
135 }
136
137 /***
138 * Creates an InMemoryFile with default permissions (0666, rw-rw-rw-)
139 */
140 public InMemoryFile(String name)
141 throws StyxException
142 {
143 this(name, 0666);
144 }
145
146 public synchronized void read(StyxFileClient client, long offset, int count,
147 int tag) throws StyxException
148 {
149 if (this.buf != null)
150 {
151
152
153 this.buf.acquire();
154 }
155 this.processAndReplyRead(this.buf, client, offset, count, tag);
156 }
157
158 public synchronized void write(StyxFileClient client, long offset,
159 int count, ByteBuffer data, boolean truncate, int tag)
160 throws StyxException
161 {
162 if (this.buf == null)
163 {
164
165 this.buf = ByteBuffer.allocate(count);
166
167 this.buf.setAutoExpand(true);
168 this.buf.position(0).limit(0);
169 log.debug("Allocated InMemoryFile with capacity " + this.buf.capacity());
170 }
171 if (offset > this.buf.limit())
172 {
173 throw new StyxException("attempt to write past the end of the file");
174 }
175
176 this.buf.position((int)offset);
177
178
179 this.buf.put(data);
180 if (truncate)
181 {
182 this.buf.limit(this.buf.position());
183 }
184 this.replyWrite(client, count, tag);
185 }
186
187 /***
188 * Set the contents of this file to the given String.
189 */
190 public synchronized void setContents(String newContents)
191 {
192
193 byte[] bytes = StyxUtils.strToUTF8(newContents);
194
195 if (this.buf == null)
196 {
197 this.buf = ByteBuffer.allocate(bytes.length);
198 this.buf.setAutoExpand(true);
199 log.debug("Allocated InMemoryFile with capacity " + this.buf.capacity());
200 }
201
202 this.buf.position(0);
203
204
205 this.buf.put(bytes);
206 this.buf.limit(bytes.length);
207
208 this.contentsChanged();
209 }
210
211 public synchronized ULong getLength()
212 {
213 if (this.buf == null)
214 {
215 return ULong.ZERO;
216 }
217 return new ULong(this.buf.limit());
218 }
219
220 /***
221 * Frees the resources associated with the file (releases the underlying
222 * ByteBuffer back to the pool). After this is called, the file can no
223 * longer be used.
224 */
225 public synchronized void delete()
226 {
227 if (this.buf != null)
228 {
229 this.buf.release();
230 }
231 }
232
233 /***
234 * Gets the data in this file as a String
235 */
236 public synchronized String getContents()
237 {
238 if (this.buf == null)
239 {
240 return "";
241 }
242
243 this.buf.position(0);
244
245 return StyxUtils.dataToString(this.buf);
246 }
247
248 public static void main (String[] args) throws Exception
249 {
250
251 StyxDirectory root = new StyxDirectory("/");
252
253 root.addChild(new InMemoryFile("inmem"));
254
255 new StyxServer(9876, root).start();
256 }
257
258 }