KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > nightlabs > util > Binary


1 /* ************************************************************************** *
2  * Copyright (C) 2004 NightLabs GmbH, Marco Schulze *
3  * All rights reserved. *
4  * http://www.NightLabs.de *
5  * *
6  * This program and the accompanying materials are free software; you can re- *
7  * distribute it and/or modify it under the terms of the GNU General Public *
8  * License as published by the Free Software Foundation; either ver 2 of the *
9  * License, or any later version. *
10  * *
11  * This module is distributed in the hope that it will be useful, but WITHOUT *
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT- *
13  * NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more *
14  * details. *
15  * *
16  * You should have received a copy of the GNU General Public License along *
17  * with this module; if not, write to the Free Software Foundation, Inc.: *
18  * 59 Temple Place, Suite 330 *
19  * Boston MA 02111-1307 *
20  * USA *
21  * *
22  * Or get it online: *
23  * http://www.opensource.org/licenses/gpl-license.php *
24  * *
25  * In case, you want to use this module or parts of it in a proprietary pro- *
26  * ject, you can purchase it under the NightLabs Commercial License. Please *
27  * contact NightLabs GmbH under info AT nightlabs DOT com for more infos or *
28  * visit http://www.NightLabs.com *
29  * ************************************************************************** */

30
31 package com.nightlabs.util;
32
33 import java.io.IOException JavaDoc;
34 import java.io.InputStream JavaDoc;
35 import java.io.OutputStream JavaDoc;
36
37 /**
38  * A helper class to read or write binary data from/to
39  * streams. This class provides methods to handle binary
40  * data in- and outputs more easily - especially
41  * reverse order number formats like they are produced using
42  * C/C++ or Pascal/Delphi raw data writing and reading
43  * functions.
44  *
45  * @author Marc Klinger <marc[at]nightlabs[dot]de>
46  * @author Daniel Mazurek
47  * @author Marco Schulze
48  */

49 public class Binary
50 {
51
52   public InputStream JavaDoc in = null;
53   public OutputStream JavaDoc out = null;
54
55   /**
56    * Initialize this Binary with an InputStream.
57    * Only the read... methods will work.
58    * @param in The InputStream to read from
59    */

60     public Binary(InputStream JavaDoc in)
61     {
62     this.in = in;
63     }
64
65   /**
66    * Initialize this Binary with an OutputStream.
67    * Only the write... methods will work.
68    * @param out The OutputStream to read from
69    */

70   public Binary(OutputStream JavaDoc out)
71     {
72     this.out = out;
73     }
74
75   /**
76    * Read a byte from the InputStream.
77    * @return The byte read.
78    * @throws IOException if a read error occurs
79    * @see InputStream#read()
80    */

81     public int read()
82     throws IOException JavaDoc
83     {
84     if (in == null)
85       throw new IllegalStateException JavaDoc("This binary is in write mode! Can't execute read()!");
86
87     return in.read();
88     }
89
90     /**
91      * Close the stream attached to this Binary.
92      * @throws IOException if an error occurs.
93      * @see InputStream#close()
94      * @see OutputStream#close()
95      */

96   public void close()
97   throws IOException JavaDoc
98   {
99         if (in != null)
100         in.close();
101         
102         if (out != null)
103         out.close();
104   }
105
106   /**
107    * Read the given number of bytes from the InputStream
108    * and reverse their order to match the Java order.
109    * @param byteCount How many bytes to use. Must be between
110    * 1 and 8.
111    * @return The number in Java byte-order
112    * @throws IOException
113    */

114   private long readReversedBytes( int byteCount )
115     throws IOException JavaDoc
116     {
117         if(byteCount > 8)
118             throw new IllegalArgumentException JavaDoc("nByteCount > 8!!!");
119         
120         if(byteCount < 1)
121             throw new IllegalArgumentException JavaDoc("nByteCount < 1!!!");
122         
123         // if( nByteCount > 8 ) nByteCount = 8;
124
// if( nByteCount < 1 ) nByteCount = 1;
125
long bBytes[] = new long[byteCount];
126         for( int i=0; i<byteCount; i++ )
127     {
128             bBytes[i] = read();
129     }
130         long nResult = 0;
131         for( int i=byteCount-1; i>0; i-- )
132     {
133             nResult = nResult | (bBytes[i] << (8*i));
134         }
135         nResult = nResult | bBytes[0];
136         return( nResult );
137     }
138     
139   public byte readByte()
140   throws IOException JavaDoc
141   {
142     return( (byte) read() );
143   }
144
145     /**
146      * Read a 2-bytes signed number as reversed binary
147      * from the input stream
148      * @return the read value as <code>short</code>
149      * @throws IOException if a read error occurs
150      */

151     public short readReversedShort()
152     throws IOException JavaDoc
153     {
154         return( (short) readReversedBytes( 2 ) );
155     }
156
157     /**
158      * Read a 2-bytes unsigned number as reversed binary
159      * from the input stream
160      * @return the read value as <code>int</code> >= 0
161      * because a Java <code>short</code> is to small.
162      * @throws IOException if a read error occurs
163      */

164     public int readReversedUnsignedShort()
165     throws IOException JavaDoc
166     {
167         return( (int) readReversedBytes( 2 ) );
168     }
169
170     /**
171      * Read a 4-bytes signed number as reversed binary
172      * from the input stream
173      * @return the read value as <code>int</code>
174      * @throws IOException if a read error occurs
175      */

176     public int readReversedInt()
177     throws IOException JavaDoc
178     {
179         return( (int) readReversedBytes( 4 ) );
180     }
181
182     /**
183      * Read a 4-bytes unsigned number as reversed binary
184      * from the input stream
185      * @return the read value as <code>long</code> >= 0
186      * because a Java <code>int</code> is to small.
187      * @throws IOException if a read error occurs
188      */

189     public long readReversedUnsignedInt()
190     throws IOException JavaDoc
191     {
192         long nTest = readReversedBytes( 4 );
193         return( nTest );
194     }
195
196     /**
197      * This method reads a zero-terminated string from the InputStream
198      * associated to this binary. The termination 0 is read from the
199      * Stream, but not part of the resulting String.
200      */

201     public String JavaDoc readString()
202     throws IOException JavaDoc
203     {
204         int c;
205         StringBuffer JavaDoc sRead = new StringBuffer JavaDoc();
206         c = read();
207         while( c != 0 ) {
208             sRead.append( (char) c );
209             c = read();
210         }
211         return( sRead.toString() );
212     }
213
214     /**
215      * This method reads the given number of bytes from the
216      * InputStream associated to this Binary. It does not stop
217      * on 0-bytes.
218      */

219     public String JavaDoc readString( int _length )
220     throws IOException JavaDoc
221     {
222         int c;
223         StringBuffer JavaDoc sRead = new StringBuffer JavaDoc();
224         for( int i=0; i<_length; i++ ) {
225             c = read();
226             sRead.append( (char) c );
227         }
228         return( sRead.toString() );
229     }
230
231     /**
232      * Read a decimal number as string from the
233      * input stream.
234      * @return The number as <code>int</code>.
235      * @throws NumberFormatException if no number can be extracted
236      * @throws IOException if a read error occurs
237      */

238     public int readNumber()
239     throws NumberFormatException JavaDoc, IOException JavaDoc
240     {
241         StringBuffer JavaDoc sRead = new StringBuffer JavaDoc();
242     if (in.markSupported())
243       in.mark(256);
244
245     boolean doReset = true;
246     try {
247       int c = read();
248       while( c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
249              c == '5' || c == '6' || c == '7' || c == '8' || c == '9' ) {
250         sRead.append( (char) c );
251         c = read();
252       }
253
254       doReset = false;
255     } finally {
256       if (doReset && in.markSupported())
257         in.reset();
258     }
259     return( Integer.parseInt( sRead.toString() ) );
260   }
261
262     /**
263      * Read an 8-bytes signed number as reversed binary
264      * from the input stream
265      * @return the read value as <code>long</code>
266      * @throws IOException if a read error occurs
267      */

268     public long readReversedLong()
269     throws IOException JavaDoc
270     {
271         long nTest = readReversedBytes( 8 );
272         return( nTest );
273     }
274
275     private void writeReversedBytes(byte[] bytes)
276     throws IOException JavaDoc
277     {
278         byte[] rBytes = new byte[bytes.length];
279         int m = 0;
280         for (int i = bytes.length - 1; i >= 0; --i)
281             rBytes[m++] = bytes[i];
282
283         out.write(rBytes);
284     }
285     
286     public void write(byte[] bytes)
287     throws IOException JavaDoc
288     {
289         out.write(bytes);
290     }
291
292     public void write(byte b)
293     throws IOException JavaDoc
294     {
295         out.write(b);
296     }
297     
298     public byte[] getByteArray(long v, int length)
299     {
300         byte b[] = new byte[length];
301         int i, shift;
302         for(i = 0, shift = (length - 1) * 8; i < length; i++, shift -= 8)
303             b[i] = (byte)(0xFF & (v >> shift));
304
305         return b;
306     }
307     
308     public void writeReversedUnsignedByte(short val)
309     throws IOException JavaDoc
310     {
311         writeReversedBytes(getByteArray(val, 1));
312     }
313     
314     public void writeReversedUnsignedShort(int val)
315     throws IOException JavaDoc
316     {
317         writeReversedBytes(getByteArray(val, 2));
318     }
319     
320     public void writeReversedShort(short val)
321     throws IOException JavaDoc
322     {
323         writeReversedBytes(getByteArray(val, 2));
324     }
325     
326     public void writeReversedUnsignedInt(long val)
327     throws IOException JavaDoc
328     {
329         writeReversedBytes(getByteArray(val, 4));
330     }
331     
332     public void writeReversedInt(int val)
333     throws IOException JavaDoc
334     {
335         writeReversedBytes(getByteArray(val, 4));
336     }
337     
338     /**
339      * This method writes a zero terminated String into the OutputStream.
340      * @param s The string to write
341      * @throws IOException
342      */

343     public void writeString(String JavaDoc s)
344     throws IOException JavaDoc
345     {
346         write(s.getBytes(CHARSET));
347         write((byte)0); // ASCII-Z
348
}
349     
350     public static String JavaDoc CHARSET = "ISO-8859-1";
351     
352     /**
353      * This method writes the given number of bytes to the OutputStream.
354      * If the String does not exactly match the defined length, an IllegalArgumentException is thrown.
355      * @param s
356      * @param length
357      * @throws IOException
358      */

359     public void writeString(String JavaDoc s, int length)
360     throws IOException JavaDoc
361     {
362         if (s.length() != length)
363             throw new IllegalArgumentException JavaDoc("Param length does not match String.length()! s=\""+s+"\" length=\""+length+"\"");
364         
365         write(s.getBytes(CHARSET));
366     }
367 }
368
Popular Tags