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