internal void Write() { var localDiagnostics = new DiagnosticBag(); ArArchiveFile.UpdateLayout(localDiagnostics); if (localDiagnostics.HasErrors) { throw new ObjectFileException("Invalid ar file", localDiagnostics); } // Copy for warnings localDiagnostics.CopyTo(Diagnostics); _startStreamOffset = Stream.Position; Stream.Write(ArArchiveFile.Magic); Span <byte> entryBuffer = stackalloc byte[ArFile.FileEntrySizeInBytes]; var headers = ArArchiveFile.LongNamesTable; // Serialize all file entries for (var i = 0; i < ArArchiveFile.Files.Count; i++) { var file = ArArchiveFile.Files[i]; // Serialize the headers at the correct position only if they are required if (headers != null && headers.Index == i && headers.Size > 0) { WriteFileEntry(entryBuffer, headers); if (Diagnostics.HasErrors) { break; } } WriteFileEntry(entryBuffer, file); if (Diagnostics.HasErrors) { break; } } if (Diagnostics.HasErrors) { throw new ObjectFileException("Unexpected error while writing ar file", Diagnostics); } }
/// <inheritdoc /> public override bool TryUpdateLayout(DiagnosticBag diagnostics) { if (diagnostics == null) { throw new ArgumentNullException(nameof(diagnostics)); } // Check first that we have a valid object file var localDiagnostics = new DiagnosticBag(); Verify(localDiagnostics); // If we have any any errors if (localDiagnostics.HasErrors) { localDiagnostics.CopyTo(diagnostics); return(false); } if (Kind == ArArchiveKind.GNU) { if (LongNamesTable == null) { LongNamesTable = new ArLongNamesTable { Parent = this }; } if (SymbolTable != null && SymbolTable.Index == 0) { LongNamesTable.Index = 1; } else { LongNamesTable.Index = 1; } // Reset the calculation of the size of headers LongNamesTable.SizeKind = ValueKind.Auto; } else { // Don't use headers LongNamesTable = null; } ulong size = (ulong)Magic.Length; // Clear the internal names foreach (var entry in Files) { entry.InternalName = null; } for (var i = 0; i < Files.Count; i++) { var entry = Files[i]; // If we have a GNU headers and they are required, add them to the offset and size if (LongNamesTable != null && LongNamesTable.Index == i) { var headerSize = LongNamesTable.Size; if (headerSize > 0) { LongNamesTable.Offset = size; size += ArFile.FileEntrySizeInBytes + LongNamesTable.Size; if ((size & 1) != 0) { size++; } } } entry.Offset = size; size += ArFile.FileEntrySizeInBytes + entry.Size; if ((size & 1) != 0) { size++; } } return(true); }