View Javadoc

1   /*
2    * Copyright (C) 2001 Ciaran Treanor <ciaran@codeloop.com>
3    *
4    * Distributable under GPL license.
5    * See terms of license at gnu.org.
6    *
7    * $Id: RRDFile.java,v 1.2 2006/12/21 18:02:42 tarus Exp $
8    */
9   package org.jrobin.core.jrrd;
10  
11  import java.io.*;
12  
13  /**
14   * This class is a quick hack to read information from an RRD file. Writing
15   * to RRD files is not currently supported. As I said, this is a quick hack.
16   * Some thought should be put into the overall design of the file IO.
17   * <p/>
18   * Currently this can read RRD files that were generated on Solaris (Sparc)
19   * and Linux (x86).
20   *
21   * @author <a href="mailto:ciaran@codeloop.com">Ciaran Treanor</a>
22   * @version $Revision: 1.2 $
23   */
24  public class RRDFile implements Constants {
25  
26  	boolean bigEndian;
27  	int alignment;
28  	RandomAccessFile ras;
29  	byte[] buffer;
30  
31  	RRDFile(String name) throws IOException {
32  		this(new File(name));
33  	}
34  
35  	RRDFile(File file) throws IOException {
36  
37  		ras = new RandomAccessFile(file, "r");
38  		buffer = new byte[128];
39  
40  		initDataLayout(file);
41  	}
42  
43  	private void initDataLayout(File file) throws IOException {
44  
45  		if (file.exists()) {	// Load the data formats from the file
46  			ras.read(buffer, 0, 24);
47  
48  			int index;
49  
50  			if ((index = indexOf(FLOAT_COOKIE_BIG_ENDIAN, buffer)) != -1) {
51  				bigEndian = true;
52  			}
53  			else if ((index = indexOf(FLOAT_COOKIE_LITTLE_ENDIAN, buffer))
54  					!= -1) {
55  				bigEndian = false;
56  			}
57  			else {
58  				throw new IOException("Invalid RRD file");
59  			}
60  
61  			switch (index) {
62  
63  				case 12:
64  					alignment = 4;
65  					break;
66  
67  				case 16:
68  					alignment = 8;
69  					break;
70  
71  				default :
72  					throw new RuntimeException("Unsupported architecture");
73  			}
74  		}
75  		else {				// Default to data formats for this hardware architecture
76  		}
77  
78  		ras.seek(0);	// Reset file pointer to start of file
79  	}
80  
81  	private int indexOf(byte[] pattern, byte[] array) {
82  		return (new String(array)).indexOf(new String(pattern));
83  	}
84  
85  	boolean isBigEndian() {
86  		return bigEndian;
87  	}
88  
89  	int getAlignment() {
90  		return alignment;
91  	}
92  
93  	double readDouble() throws IOException {
94  
95  		//double value;
96  		byte[] tx = new byte[8];
97  
98  		ras.read(buffer, 0, 8);
99  
100 		if (bigEndian) {
101 			tx = buffer;
102 		}
103 		else {
104 			for (int i = 0; i < 8; i++) {
105 				tx[7 - i] = buffer[i];
106 			}
107 		}
108 
109 		DataInputStream reverseDis =
110 				new DataInputStream(new ByteArrayInputStream(tx));
111 
112 		return reverseDis.readDouble();
113 	}
114 
115 	int readInt() throws IOException {
116 		return readInt(false);
117 	}
118 
119 	int readInt(boolean dump) throws IOException {
120 
121 		ras.read(buffer, 0, 4);
122 
123 		int value;
124 
125 		if (bigEndian) {
126 			value = (0xFF & buffer[3]) | ((0xFF & buffer[2]) << 8)
127 					| ((0xFF & buffer[1]) << 16) | ((0xFF & buffer[0]) << 24);
128 		}
129 		else {
130 			value = (0xFF & buffer[0]) | ((0xFF & buffer[1]) << 8)
131 					| ((0xFF & buffer[2]) << 16) | ((0xFF & buffer[3]) << 24);
132 		}
133 
134 		return value;
135 	}
136 
137 	String readString(int maxLength) throws IOException {
138 
139 		ras.read(buffer, 0, maxLength);
140 
141 		return new String(buffer, 0, maxLength).trim();
142 	}
143 
144 	void skipBytes(int n) throws IOException {
145 		ras.skipBytes(n);
146 	}
147 
148 	int align(int boundary) throws IOException {
149 
150 		int skip = (int) (boundary - (ras.getFilePointer() % boundary)) % boundary;
151 
152 		if (skip != 0) {
153 			ras.skipBytes(skip);
154 		}
155 
156 		return skip;
157 	}
158 
159 	int align() throws IOException {
160 		return align(alignment);
161 	}
162 
163 	long info() throws IOException {
164 		return ras.getFilePointer();
165 	}
166 
167 	long getFilePointer() throws IOException {
168 		return ras.getFilePointer();
169 	}
170 
171 	void close() throws IOException {
172 		ras.close();
173 	}
174 }