View Javadoc
1   /*
2    * #%L
3    * nom.tam FITS library
4    * %%
5    * Copyright (C) 2004 - 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  package nom.tam.util;
32  
33  import java.io.DataOutput;
34  import java.io.DataOutputStream;
35  import java.io.IOException;
36  import java.io.OutputStream;
37  
38  /**
39   * For writing FITS files through an {@link OutputStream}.
40   * <p>
41   * Testing and timing for this class is performed in the nom.tam.util.test.BufferedFileTester class.
42   * <p>
43   * Version 2.0 -- October 30, 2021: Completely overhauled, with new name and hierarchy. Performance is 2-4 times better
44   * than before. (Attila Kovacs)
45   *
46   * @see FitsInputStream
47   * @see FitsFile
48   */
49  @SuppressWarnings("deprecation")
50  public class FitsOutputStream extends ArrayOutputStream implements FitsOutput {
51  
52      /** the output, as accessible via the <code>DataInput</code> interface */
53      private final DataOutput data;
54  
55      /** Unencoded output byte count */
56      private int unencodedCount;
57  
58      /**
59       * Use the BufferedOutputStream constructor
60       *
61       * @param o An open output stream.
62       */
63      public FitsOutputStream(OutputStream o) {
64          this(o, FitsIO.DEFAULT_BUFFER_SIZE);
65      }
66  
67      /**
68       * Use the BufferedOutputStream constructor
69       *
70       * @param o         An open output stream.
71       * @param bufLength The buffer size.
72       */
73      public FitsOutputStream(OutputStream o, int bufLength) {
74          super(o, bufLength);
75          setEncoder(new FitsEncoder(this));
76          if (o instanceof DataOutput) {
77              data = (DataOutput) o;
78          } else {
79              data = new DataOutputStream(o);
80          }
81      }
82  
83      @Override
84      protected FitsEncoder getEncoder() {
85          return (FitsEncoder) super.getEncoder();
86      }
87  
88      @Override
89      public void write(int b) throws IOException {
90          super.write(b);
91          unencodedCount++;
92      }
93  
94      @Override
95      public void write(byte[] b, int start, int length) throws IOException {
96          super.write(b, start, length);
97          unencodedCount += length;
98      }
99  
100     @Override
101     public void write(boolean[] b, int start, int length) throws IOException {
102         getEncoder().write(b, start, length);
103     }
104 
105     @Override
106     public void write(Boolean[] buf, int offset, int size) throws IOException {
107         getEncoder().write(buf, offset, size);
108     }
109 
110     @Override
111     public void write(char[] c, int start, int length) throws IOException {
112         getEncoder().write(c, start, length);
113     }
114 
115     @Override
116     public void write(short[] s, int start, int length) throws IOException {
117         getEncoder().write(s, start, length);
118     }
119 
120     @Override
121     public void write(int[] i, int start, int length) throws IOException {
122         getEncoder().write(i, start, length);
123     }
124 
125     @Override
126     public void write(long[] l, int start, int length) throws IOException {
127         getEncoder().write(l, start, length);
128     }
129 
130     @Override
131     public void write(float[] f, int start, int length) throws IOException {
132         getEncoder().write(f, start, length);
133     }
134 
135     @Override
136     public void write(double[] d, int start, int length) throws IOException {
137         getEncoder().write(d, start, length);
138     }
139 
140     @Override
141     public void writeBytes(String s) throws IOException {
142         getEncoder().writeBytes(s);
143     }
144 
145     @Override
146     public void writeChars(String s) throws IOException {
147         getEncoder().writeChars(s);
148     }
149 
150     @Override
151     public void writeUTF(String s) throws IOException {
152         data.writeUTF(s);
153     }
154 
155     @Override
156     public void write(String[] s, int start, int len) throws IOException {
157         getEncoder().write(s, start, len);
158     }
159 
160     @Override
161     public void writeByte(int b) throws IOException {
162         getEncoder().writeByte(b);
163     }
164 
165     @Override
166     public void writeBoolean(boolean b) throws IOException {
167         getEncoder().writeBoolean(b);
168     }
169 
170     @Override
171     public void writeChar(int c) throws IOException {
172         getEncoder().writeChar(c);
173     }
174 
175     @Override
176     public void writeShort(int s) throws IOException {
177         getEncoder().writeShort(s);
178     }
179 
180     @Override
181     public void writeInt(int i) throws IOException {
182         getEncoder().writeInt(i);
183     }
184 
185     @Override
186     public void writeLong(long l) throws IOException {
187         getEncoder().writeLong(l);
188     }
189 
190     @Override
191     public void writeFloat(float f) throws IOException {
192         getEncoder().writeFloat(f);
193     }
194 
195     @Override
196     public void writeDouble(double d) throws IOException {
197         getEncoder().writeDouble(d);
198     }
199 
200     /**
201      * Deprecated use {@link #writeArray(Object)}.
202      *
203      * @param      o           The object to be written.
204      *
205      * @throws     IOException if one of the underlying write operations failed
206      *
207      * @deprecated             use {@link #writeArray(Object)} instead
208      */
209     @Deprecated
210     public final void writePrimitiveArray(Object o) throws IOException {
211         writeArray(o);
212     }
213 
214     @Override
215     public boolean isAtStart() {
216         return (unencodedCount + getEncoder().getCount()) == 0;
217     }
218 
219 }