/// <summary> /// Reads a file structure from an open stream. /// </summary> /// <param name="stream">Stream to read from.</param> /// <returns>File structure populated from the stream.</returns> public static FileStructure Read(Stream stream) { FileStructure fs = new FileStructure(); using (NonClosingStreamWrapper wrapper = new NonClosingStreamWrapper(stream)) using (BinaryReader reader = new BinaryReader(wrapper)) { fs.FileFormat = FileStructure.ReadFileFormat(reader); if (FileFormat.Unknown != fs.FileFormat) { fs.embeddedFileSizes = FileStructure.ReadEmbeddedFileSizes(reader); // Remember the data stream offset, which is right after the embedded files have been written. fs.dataStreamOffset = stream.Position; foreach (long size in fs.embeddedFileSizes) { fs.dataStreamOffset += size; } } } fs.stream = stream; return(fs); }
/// <summary> /// Writes the table in IDT format to the provided stream. /// </summary> /// <param name="writer">Stream to write the table to.</param> /// <param name="keepAddedColumns">Whether to keep columns added in a transform.</param> public void ToIdtDefinition(StreamWriter writer, bool keepAddedColumns) { if (this.Definition.Unreal) { return; } if (TableDefinition.MaxColumnsInRealTable < this.Definition.Columns.Count) { throw new WixException(WixDataErrors.TooManyColumnsInRealTable(this.Definition.Name, this.Definition.Columns.Count, TableDefinition.MaxColumnsInRealTable)); } // Tack on the table header, and flush before we start writing bytes directly to the stream. writer.Write(this.Definition.ToIdtDefinition(keepAddedColumns)); writer.Flush(); using (NonClosingStreamWrapper wrapper = new NonClosingStreamWrapper(writer.BaseStream)) using (BufferedStream buffStream = new BufferedStream(wrapper)) { // Create an encoding that replaces characters with question marks, and doesn't throw. We'll // use this in case of errors Encoding convertEncoding = Encoding.GetEncoding(writer.Encoding.CodePage); foreach (Row row in this.Rows) { if (row.Redundant) { continue; } string rowString = row.ToIdtDefinition(keepAddedColumns); byte[] rowBytes; try { // GetBytes will throw an exception if any character doesn't match our current encoding rowBytes = writer.Encoding.GetBytes(rowString); } catch (EncoderFallbackException) { Messaging.Instance.OnMessage(WixDataErrors.InvalidStringForCodepage(row.SourceLineNumbers, Convert.ToString(writer.Encoding.WindowsCodePage, CultureInfo.InvariantCulture))); rowBytes = convertEncoding.GetBytes(rowString); } buffStream.Write(rowBytes, 0, rowBytes.Length); } } }
/// <summary> /// Creates a new file structure. /// </summary> /// <param name="stream">Stream to write the file structure to.</param> /// <param name="fileFormat">File format for the file structure.</param> /// <param name="embedFilePaths">Paths to files to embedd in the file structure.</param> /// <returns>Newly created file structure.</returns> public static FileStructure Create(Stream stream, FileFormat fileFormat, List <string> embedFilePaths) { FileStructure fs = new FileStructure(); using (NonClosingStreamWrapper wrapper = new NonClosingStreamWrapper(stream)) using (BinaryWriter writer = new BinaryWriter(wrapper)) { fs.WriteType(writer, fileFormat); fs.WriteEmbeddedFiles(writer, embedFilePaths ?? new List <string>()); // Remember the data stream offset, which is right after the embedded files have been written. fs.dataStreamOffset = stream.Position; } fs.stream = stream; return(fs); }
/// <summary> /// Probes a stream to determine the file format. /// </summary> /// <param name="stream">Stream to test.</param> /// <returns>The file format.</returns> public static FileFormat TestFileFormat(Stream stream) { FileFormat format = FileFormat.Unknown; long position = stream.Position; try { using (NonClosingStreamWrapper wrapper = new NonClosingStreamWrapper(stream)) using (BinaryReader reader = new BinaryReader(wrapper)) { format = FileStructure.ReadFileFormat(reader); } } finally { stream.Seek(position, SeekOrigin.Begin); } return(format); }