1 /***
2 *
3 * Copyright 2004 Protique Ltd
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18
19 package org.codehaus.activemq.message.util;
20 import java.io.File;
21 import java.io.IOException;
22 import java.io.RandomAccessFile;
23
24 /***
25 * Simply writes/reads data from a RandomAccessFile
26 *
27 * @version $Revision: 1.1 $
28 */
29 class FileDataBlock {
30 private RandomAccessFile dataBlock;
31 private File file;
32 private long maxSize;
33 private long currentOffset;
34
35 /***
36 * Constructor
37 *
38 * @param file File handle
39 * @param maxSize maximum size (in bytes) for the block
40 * @throws IOException
41 */
42 FileDataBlock(File file, long maxSize) throws IOException {
43 this.file = file;
44 this.maxSize = maxSize;
45 this.dataBlock = new RandomAccessFile(file, "rw");
46 if (dataBlock.length() > 0) {
47 this.currentOffset = dataBlock.readLong();
48 }
49 else {
50 dataBlock.writeLong(0);
51 currentOffset = dataBlock.length();
52 }
53 }
54
55 /***
56 * close and deletes the block
57 *
58 * @throws IOException
59 */
60 synchronized void close() throws IOException {
61 dataBlock.close();
62 file.delete();
63 }
64
65 /***
66 * test to if there is enough room in the block to write the data
67 *
68 * @param data bytes to be written
69 * @return true if there is enough space left in the block to write the data
70 * @throws IOException
71 */
72 synchronized boolean isEnoughSpace(byte[] data) throws IOException {
73 return ((dataBlock.length() + data.length) < maxSize);
74 }
75
76 /***
77 * Write data to the end of the block
78 *
79 * @param data the bytes to write
80 * @throws IOException
81 */
82 synchronized void write(byte[] data) throws IOException {
83 dataBlock.seek(dataBlock.length());
84 dataBlock.writeInt(data.length);
85 dataBlock.write(data);
86 }
87
88 /***
89 * read next chunk of data
90 *
91 * @return next chunk of data or null if no more to read
92 * @throws IOException
93 */
94 synchronized byte[] read() throws IOException {
95 byte[] result = null;
96 if (currentOffset > 0 && currentOffset < dataBlock.length()) {
97 dataBlock.seek(currentOffset);
98 int length = dataBlock.readInt();
99 result = new byte[length];
100 dataBlock.readFully(result);
101 currentOffset = dataBlock.getFilePointer();
102 updateHeader(currentOffset);
103 }
104 return result;
105 }
106
107 private void updateHeader(long pos) throws IOException {
108 dataBlock.seek(0);
109 dataBlock.writeLong(pos);
110 }
111 }