View Javadoc
1   /*
2    * #%L
3    * nom.tam FITS library
4    * %%
5    * Copyright (C) 1996 - 2024 nom-tam-fits
6    * %%
7    * This is free and unencumbered software released into the public domain.
8    *
9    * Anyone is free to copy, modify, publish, use, compile, sell, or
10   * distribute this software, either in source code form or as a compiled
11   * binary, for any purpose, commercial or non-commercial, and by any
12   * means.
13   *
14   * In jurisdictions that recognize copyright laws, the author or authors
15   * of this software dedicate any and all copyright interest in the
16   * software to the public domain. We make this dedication for the benefit
17   * of the public at large and to the detriment of our heirs and
18   * successors. We intend this dedication to be an overt act of
19   * relinquishment in perpetuity of all present and future rights to this
20   * software under copyright law.
21   *
22   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28   * OTHER DEALINGS IN THE SOFTWARE.
29   * #L%
30   */
31  
32  package nom.tam.util;
33  
34  import java.io.BufferedInputStream;
35  import java.io.EOFException;
36  import java.io.IOException;
37  import java.io.InputStream;
38  
39  /**
40   * Efficient reading of binary arrays from streams with custom binary encoding.
41   * 
42   * @author Attila Kovacs
43   * @since 1.16
44   * @see ArrayOutputStream
45   * @see ArrayDataFile
46   */
47  public class ArrayInputStream extends BufferedInputStream implements InputReader {
48  
49      /** conversion from FITS binary representation to Java arrays */
50      private InputDecoder decoder;
51  
52      /**
53       * Instantiates a new input stream for efficient array transactions. For use
54       * by subclass constructors only.
55       * 
56       * @param i
57       *            the underlying input stream
58       * @param bufLength
59       *            the buffer size in bytes.
60       */
61      protected ArrayInputStream(InputStream i, int bufLength) {
62          super(i, bufLength);
63      }
64  
65      /**
66       * Instantiates a new input stream for efficient array transactions.
67       * 
68       * @param i
69       *            the underlying input stream
70       * @param bufLength
71       *            the buffer size in bytes.
72       * @param bin2java
73       *            the conversion from the binary representation of arrays in the
74       *            file to Java arrays.
75       */
76      ArrayInputStream(InputStream i, int bufLength, InputDecoder bin2java) {
77          this(i, bufLength);
78          setDecoder(bin2java);
79      }
80  
81      /**
82       * Sets the conversion from the binary representation of arrays in stream to
83       * Java arrays. For use by subclass constructors only.
84       * 
85       * @param bin2java
86       *            the conversion from the binary representation of arrays in the
87       *            stream to Java arrays.
88       * @see #getDecoder()
89       */
90      protected void setDecoder(InputDecoder bin2java) {
91          decoder = bin2java;
92      }
93  
94      /**
95       * Returns the conversion from the binary representation of arrays in stream
96       * to Java arrays. Subclass implementeations can use this to access the
97       * required conversion when writing data to file.
98       * 
99       * @return the conversion from the binary representation of arrays in the
100      *         stream to Java arrays
101      * @see #setDecoder(InputDecoder)
102      */
103     protected InputDecoder getDecoder() {
104         return decoder;
105     }
106 
107     /**
108      * See {@link ArrayDataInput#readLArray(Object)} for a contract of this
109      * method.
110      * 
111      * @param o
112      *            an array, to be populated
113      * @return the actual number of bytes read from the input, or -1 if already
114      *         at the end-of-file.
115      * @throws IllegalArgumentException
116      *             if the argument is not an array or if it contains an element
117      *             that is not supported for decoding.
118      * @throws IOException
119      *             if there was an IO error reading from the input
120      * @see #readArrayFully(Object)
121      */
122     public synchronized long readLArray(Object o) throws IOException, IllegalArgumentException {
123         try {
124             return decoder.readArray(o);
125         } catch (IllegalArgumentException e) {
126             throw new IOException(e);
127         }
128     }
129 
130     /**
131      * See {@link ArrayDataInput#readArrayFully(Object)} for a contract of this
132      * method.
133      * 
134      * @param o
135      *            an array, to be populated
136      * @throws IllegalArgumentException
137      *             if the argument is not an array or if it contains an element
138      *             that is not supported for decoding.
139      * @throws IOException
140      *             if there was an IO error reading from the input
141      * @see #readLArray(Object)
142      * @see #readImage(Object)
143      */
144     public synchronized void readArrayFully(Object o) throws IOException, IllegalArgumentException {
145         decoder.readArrayFully(o);
146     }
147 
148     /**
149      * Like {@link #readArrayFully(Object)} but strictly for numerical types
150      * only.
151      * 
152      * @param o
153      *            An any-dimensional array containing only numerical types
154      * @throws IllegalArgumentException
155      *             if the argument is not an array or if it contains an element
156      *             that is not supported.
157      * @throws EOFException
158      *             if already at the end of file.
159      * @throws IOException
160      *             if there was an IO error
161      * @see #readArrayFully(Object)
162      * @since 1.18
163      */
164     public void readImage(Object o) throws EOFException, IOException, IllegalArgumentException {
165         decoder.readImage(o);
166     }
167 
168 }