View Javadoc
1   package nom.tam.util;
2   
3   /*
4    * #%L
5    * nom.tam FITS library
6    * %%
7    * Copyright (C) 1996 - 2024 nom-tam-fits
8    * %%
9    * This is free and unencumbered software released into the public domain.
10   *
11   * Anyone is free to copy, modify, publish, use, compile, sell, or
12   * distribute this software, either in source code form or as a compiled
13   * binary, for any purpose, commercial or non-commercial, and by any
14   * means.
15   *
16   * In jurisdictions that recognize copyright laws, the author or authors
17   * of this software dedicate any and all copyright interest in the
18   * software to the public domain. We make this dedication for the benefit
19   * of the public at large and to the detriment of our heirs and
20   * successors. We intend this dedication to be an overt act of
21   * relinquishment in perpetuity of all present and future rights to this
22   * software under copyright law.
23   *
24   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
28   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30   * OTHER DEALINGS IN THE SOFTWARE.
31   * #L%
32   */
33  
34  import java.io.EOFException;
35  import java.io.IOException;
36  
37  /**
38   * @deprecated Use {@link FitsDecoder} instead which provides a similar function but in a more consistent way and with a
39   *                 less misleading name. This is a rusty rail implementation for of an older abandoned class only,
40   *                 unsafe for general use. For reading non-FITS encoding you may also use {@link InputDecoder} as a base
41   *                 for implementing efficient custom decoding of binary inputs in general.
42   *
43   * @see        FitsDecoder
44   */
45  @Deprecated
46  public abstract class BufferDecoder extends FitsDecoder {
47  
48      private BufferPointer p;
49  
50      /**
51       * @param p Unused, but the position and length fields are set/reset as to pretend that half of the buffer is
52       *              perpetually available for reading. However, at no point will there be any data actually in the
53       *              buffer of this object, and you should by all means avoid directly loading data from the stream into
54       *              this dead-end buffer, other than the hopefully untiggered existing implementation of
55       *              <code>checkBuffer(int)</code> (and it's safest if you don't override or ever call
56       *              <code>checkBuffer(int)</code> from your code!).
57       */
58      public BufferDecoder(BufferPointer p) {
59          super();
60  
61          this.p = p;
62  
63          pretendHalfPopulated();
64  
65          setInput(new InputReader() {
66              private byte[] b1 = new byte[1];
67  
68              @Override
69              public int read() throws IOException {
70                  int n = BufferDecoder.this.read(b1, 0, 1);
71                  if (n < 0) {
72                      return n;
73                  }
74                  return b1[0];
75              }
76  
77              @Override
78              public int read(byte[] b, int from, int length) throws IOException {
79                  return BufferDecoder.this.read(b, from, length);
80              }
81          });
82      }
83  
84      /**
85       * We'll always pretend the buffer to be half populated at pos=0, in order to avoid triggering a read from the input
86       * into the unused buffer of BufferPointer, or a write to the output from that buffer... If the pointer has no
87       * buffer, length will be 0 also.
88       */
89      private void pretendHalfPopulated() {
90          p.pos = 0;
91          p.length = p.buffer == null ? 0 : p.buffer.length >>> 1;
92      }
93  
94      @Override
95      boolean makeAvailable(int needBytes) throws IOException {
96          pretendHalfPopulated();
97          boolean result = super.makeAvailable(needBytes);
98          return result;
99      }
100 
101     /**
102      * @deprecated             No longer used internally, kept only for back-compatibility since it used to be a needed
103      *                             abstract method. It's safest if you never override or call this method from your
104      *                             code!
105      *
106      * @param      needBytes   the number of byte we need available to decode the next element
107      *
108      * @throws     IOException if the data could not be made available due to an IO error of the underlying input.
109      */
110     @Deprecated
111     protected void checkBuffer(int needBytes) throws IOException {
112     }
113 
114     @Override
115     protected int read(byte[] buf, int offset, int length) throws IOException {
116         throw new UnsupportedOperationException(
117                 "You need to override this with an implementation that reads from the desired input.");
118     }
119 
120     /**
121      * @deprecated              No longer used internally, kept only for back-compatibility since it used to be a needed
122      *                              abstract method.
123      *
124      * @param      e            the <code>EOFException</code> thrown by one of the read calls.
125      * @param      start        the index of the first array element we wanted to fill
126      * @param      index        the array index of the element during which the exception was thrown
127      * @param      elementSize  the number of bytes per element we were processing
128      *
129      * @return                  the numer of bytes successfully processed from the input before the exception occurred.
130      *
131      * @throws     EOFException if the input had no more data to process
132      */
133     @Deprecated
134     protected int eofCheck(EOFException e, int start, int index, int elementSize) throws EOFException {
135         return (int) super.eofCheck(e, (index - start), -1) * elementSize;
136     }
137 
138     /**
139      * See the contract of {@link ArrayDataInput#readLArray(Object)}.
140      *
141      * @param  o                        an array, to be populated
142      *
143      * @return                          the actual number of bytes read from the input, or -1 if already at the
144      *                                      end-of-file.
145      *
146      * @throws IllegalArgumentException if the argument is not an array or if it contains an element that is not
147      *                                      supported for decoding.
148      * @throws IOException              if there was an IO error reading from the input
149      */
150     protected long readLArray(Object o) throws IOException {
151         try {
152             return super.readArray(o);
153         } catch (IllegalArgumentException e) {
154             throw new IOException(e);
155         }
156     }
157 
158 }