public override void Write(ArrayDataIO s) { System.Threading.Monitor.Enter(this); //((Writer)_writerMap[new Config(_rs.NRows != RowSource.NA, _hasStrings, s.CanSeek, _writeMode)]).Write(s); Config c = new Config(_rs.NRows != RowSource.NA, _hasStrings, s.CanSeek, _writeMode); ((Writer)_writerMap[c]).Write(s); s.Flush(); System.Threading.Monitor.Exit(this); }
/// <summary> /// method to write data /// </summary> /// <param name="o"></param> public override void Write(ArrayDataIO o) { // Don't need to write null data (noted by Jens Knudstrup) if (byteSize == 0) { return; } // changes suggested in .97 version: if (dataArray == null) { if (tiler != null) { // Need to read in the whole image first. try { dataArray = tiler.CompleteImage; } catch (IOException) { throw new FitsException("Error attempting to fill image"); } } else if (dataArray == null && dataDescription != null) { // Need to create an array to match a specified header. dataArray = ArrayFuncs.NewInstance(dataDescription.type, dataDescription.dims); } else { // This image isn't ready to be written! throw new FitsException("Null image data"); } } try { o.WriteArray(dataArray); } catch (IOException e) { throw new FitsException("IO Error on image write: " + e); } byte[] padding = new byte[FitsUtil.Padding(TrueSize)]; try { o.Write(padding); o.Flush(); } catch (IOException e) { throw new FitsException("Error writing padding: " + e); } }
/// <summary>Write the RandomGroupsData.</summary> public override void Write(ArrayDataIO str) { try { str.WriteArray(dataArray); byte[] padding = new byte[FitsUtil.Padding(TrueSize)]; str.Write(padding); str.Flush(); } catch (IOException e) { throw new FitsException("IO error writing random groups data " + e); } }
/// <summary>Write out the HDU.</summary> public virtual void Write(ArrayDataIO stream) { if (myHeader != null) { myHeader.Write(stream); } if (myData != null) { myData.Write(stream); } try { stream.Flush(); } catch (IOException e) { throw new FitsException("Error flushing at end of HDU: " + e.Message); } }
/// <summary> /// Writes this binary table with heap temp file if necessary, /// then fixing nRows and PCOUNT in header, /// then if necessary copying heap file to destination stream. /// </summary> /// <param name="s">The destination stream.</param> /// steps: /// 1) write the header to the main stream /// write the table to the main stream /// byterenderers write data to the heap if necessary /// byterenderers return heap positions and lengths if necessary /// these are returned as a byte sequence like any other data /// and are written to the table like any other data /// 2) fix the header /// 3) write the heap tempfile to the main stream /// what a pain protected void WriteHeapOutputWithTempHeapFile(ArrayDataIO s) { String heapFilename = CreateTempFilename() + "heap.tmp"; HeapStream heapS = null; int[] maxColWidths = null; if (_hasStrings) { maxColWidths = new int[_byteRenderers.Length]; heapS = new HeapStream(new FileStream(heapFilename, FileMode.Create)); for (int col = 0; col < _byteRenderers.Length; ++col) { _byteRenderers[col].Heap = heapS; maxColWidths[col] = -1; } } #region 1) write the header and the table // prep header to make sure it will line up properly with the table later on. // since we made the header, we know that anything we add later // (except THEAP, accounted for here) will already have been there, // so we're not inflating the header myHeader.RemoveCard("THEAP"); if (_hasStrings && _writeMode == StringWriteMode.HEAP) { myHeader.AddValue("THEAP", 0, null); } long headerMark = s.Position; myHeader.Write(s); int nRows = 0; for (Array[] els = _rs.GetNextRow(ref _row); els != null;) { ++nRows; for (int col = 0; col < _byteRenderers.Length; ++col) { _byteRenderers[col].Write(els[col], s); if (els[col] is String[]) { maxColWidths[col] = maxColWidths[col] < ((String[])els[col])[0].Length ? ((String[])els[col])[0].Length : maxColWidths[col]; } } els = _rs.GetNextRow(ref _row); } // pad the table. if there's a heap, pad the heap instead if (!_hasStrings) { int pad = FitsUtil.Padding((long)nRows * (long)_rowSizeInBytes); s.Write(new byte[pad], 0, pad); } s.Flush(); #endregion #region 2) fix the header and write it to the main stream myHeader.RemoveCard("NAXIS2"); myHeader.SetNaxis(2, nRows); // shoehorn correct heap information into header // PCOUNT, THEAP, and TFORMn // fix NAXIS1 if (_hasStrings) { long theap = (long)nRows * (long)_rowSizeInBytes; int pad = FitsUtil.Padding(theap + heapS.Position); int pcount = (int)heapS.Position + pad; // here we correct for swapping out actual strings with heap indices/lengths myHeader.RemoveCard("NAXIS1"); myHeader.InsertCard(new HeaderCard("NAXIS1", _rowSizeInBytes, null), "NAXIS2"); myHeader.RemoveCard("PCOUNT"); myHeader.InsertCard(new HeaderCard("PCOUNT", pcount, "Length of heap area in bytes"), "GCOUNT"); myHeader.RemoveCard("THEAP"); // can't fit a long in here! if (pcount > 0 && _writeMode == StringWriteMode.HEAP) { myHeader.AddValue("THEAP", (int)theap, "Position of heap wrt start of binary table"); } // fix the TFORMn entries for string columns IEnumerator ie = null; bool found = false; for (int i = 0; i < maxColWidths.Length; ++i, found = false) { if (maxColWidths[i] > -1) { ie = myHeader.GetEnumerator(); ie.MoveNext(); for (int j = 0; !found && ie.Current != null; ++j, ie.MoveNext()) { if (("TFORM" + (i + 1)).Equals(((DictionaryEntry)ie.Current).Key)) { myHeader.RemoveCard(j); myHeader. InsertCard(new HeaderCard("TFORM" + (i + 1), "1PA(" + maxColWidths[i] + ")", null), j); found = true; } } } } } // rewrite the header long heapMark = s.Position; s.Seek(headerMark, SeekOrigin.Begin); myHeader.Write(s); #endregion #region 3) write the heap tempfile to the main stream if (_hasStrings) { // calculate the pad int pad = FitsUtil.Padding((long)nRows * (long)_rowSizeInBytes + heapS.Position); s.Seek(heapMark, SeekOrigin.Begin); // write heap to the main stream heapS.Seek(0, SeekOrigin.Begin); for (int nRead = heapS.Read(_buf, 0, _buf.Length); nRead > 0;) { s.Write(_buf, 0, nRead); nRead = heapS.Read(_buf, 0, _buf.Length); } heapS.Close(); File.Delete(heapFilename); // pad the file s.Write(new byte[pad], 0, pad); } #endregion }
/// <summary>Write the data to an output stream.</summary> public override void Write(ArrayDataIO str) { // If buffer is still around we can just reuse it, // since nothing we've done has invalidated it. if (buffer == null) { if (data == null) { throw new FitsException("Attempt to write undefined ASCII Table"); } buffer = new byte[nRows * rowLen]; bp = new ByteParser(buffer); for (int i = 0; i < buffer.Length; i += 1) { buffer[i] = (byte)' '; //SupportClass.Identity(' '); } ByteFormatter bf = new ByteFormatter(); bf.TruncationThrow = false; bf.TruncateOnOverflow = true; for (int i = 0; i < nRows; i += 1) { for (int j = 0; j < nFields; j += 1) { int offset = i * rowLen + offsets[j]; int len = lengths[j]; try { if (isNull_Renamed_Field != null && isNull_Renamed_Field[i * nFields + j]) { if (nulls[j] == null) { throw new FitsException("No null value set when needed"); } bf.format(nulls[j], buffer, offset, len); } else { if (types[j] == typeof(String)) { String[] s = (String[])data[j]; bf.format(s[i], buffer, offset, len); } else if (types[j] == typeof(int)) { int[] ia = (int[])data[j]; bf.format(ia[i], buffer, offset, len); } else if (types[j] == typeof(float)) { float[] fa = (float[])data[j]; bf.format(fa[i], buffer, offset, len); } else if (types[j] == typeof(double)) { double[] da = (double[])data[j]; bf.format(da[i], buffer, offset, len); } else if (types[j] == typeof(long)) { long[] la = (long[])data[j]; bf.format(la[i], buffer, offset, len); } } } catch (TruncationException) { Console.Error.WriteLine("Ignoring truncation error:" + i + "," + j); } } } } // Now write the buffer. try { str.Write(buffer); byte[] padding = new byte[FitsUtil.Padding(buffer.Length)]; for (int i = 0; i < padding.Length; i += 1) { padding[i] = (byte)SupportClass.Identity(' '); } if (buffer.Length > 0) { str.Write(padding); } str.Flush(); } catch (IOException) { throw new FitsException("Error writing ASCII Table data"); } }