bool ReadEcfFromStream() { bool result = true; result = EcfHeader.VerifyIsEcf(mEcfStream.Reader); if (!result) { if (VerboseOutput != null) { VerboseOutput.WriteLine("\tFailed: File is either not even an ECF-based file, or corrupt"); } } else { mEcfFile = new EcfFile(); mEcfFile.Serialize(mEcfStream); } return(result); }
bool BuildInternal(string workPath, string outputPath) { EcfDefinition.WorkingDirectory = workPath; string ecf_name = EcfDefinition.EcfName; if (ecf_name.IsNotNullOrEmpty()) { ecf_name = Path.GetFileNameWithoutExtension(mSourceFile); } string ecf_filename = Path.Combine(outputPath, ecf_name); #if false // I'm no longer doing this since we don't strip the file ext off listing when expanding // #TODO I bet a user could forget to include the preceding dot if (EcfDefinition.EcfFileExtension.IsNotNullOrEmpty()) { ecf_filename += EcfDefinition.EcfFileExtension; } #endif if (File.Exists(ecf_filename)) { var attrs = File.GetAttributes(ecf_filename); if (attrs.HasFlag(FileAttributes.ReadOnly)) { throw new IOException("ECF file is readonly, can't build: " + ecf_filename); } } mEcfFile = new EcfFile(); mEcfFile.SetupHeaderAndChunks(EcfDefinition); const FA k_mode = FA.Write; const int k_initial_buffer_size = 8 * IntegerMath.kMega; // 8MB if (ProgressOutput != null) { ProgressOutput.WriteLine("Building {0} to {1}...", ecf_name, outputPath); } if (ProgressOutput != null) { ProgressOutput.WriteLine("\tAllocating memory..."); } bool result = true; using (var ms = new MemoryStream(k_initial_buffer_size)) using (var ecf_memory = new IO.EndianStream(ms, Shell.EndianFormat.Big, this, permissions: k_mode)) { ecf_memory.StreamMode = k_mode; ecf_memory.VirtualAddressTranslationInitialize(Shell.ProcessorSize.x32); long preamble_size = mEcfFile.CalculateHeaderAndChunkEntriesSize(); ms.SetLength(preamble_size); ms.Seek(preamble_size, SeekOrigin.Begin); // now we can start embedding the files if (ProgressOutput != null) { ProgressOutput.WriteLine("\tPacking chunks..."); } result = result && PackChunks(ecf_memory); if (result) { if (ProgressOutput != null) { ProgressOutput.WriteLine("\tFinializing..."); } // seek back to the start of the ECF and write out the finalized header and chunk descriptors ms.Seek(0, SeekOrigin.Begin); mEcfFile.Serialize(ecf_memory); Contract.Assert(ecf_memory.BaseStream.Position == preamble_size, "Written ECF header size is NOT EQUAL what we calculated"); // Update sizes and checksums ms.Seek(0, SeekOrigin.Begin); mEcfFile.SerializeBegin(ecf_memory, isFinalizing: true); mEcfFile.SerializeEnd(ecf_memory); // finally, bake the ECF memory stream into a file using (var fs = new FileStream(ecf_filename, FileMode.Create, FA.Write)) ms.WriteTo(fs); } } return(result); }