src/managed/DiffGen/archives/CpioArchives/BinaryCpioArchive.cs (68 lines of code) (raw):

/** * @file BinaryCpioArchive.cs * * @copyright Copyright (c) Microsoft Corporation. * Licensed under the MIT License. */ namespace CpioArchives { using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using ArchiveUtility; [SuppressMessage("Microsoft.StyleCop.CSharp.ReadabilityRules", "SA1121", Justification = "We want to be explicit about bit-width using these aliases.")] public class BinaryCpioArchive : CpioArchiveBase { private const int CpioBinaryHeaderSize = 26; private const uint BinaryMagic = 0x71C7; // 070707 in octal public BinaryCpioArchive(ArchiveLoaderContext context) : base(context) { } public override string ArchiveSubtype { get { return "binary"; } } protected override HeaderDetails ReadHeader(BinaryReader reader) { byte[] rawData = new byte[CpioBinaryHeaderSize]; if (reader.Read(rawData, 0, CpioBinaryHeaderSize) != CpioBinaryHeaderSize) { throw new FormatException("Not enough data present to store a CPIO binary header"); } var magic = (uint)rawData[0] + (0x100u * (uint)rawData[1]); if (magic != BinaryMagic) { throw new FormatException("Magic constant not detected."); } var dev = rawData[2] + (0x100u * rawData[3]); var ino = rawData[4] + (0x100u * rawData[5]); var mode = rawData[6] + (0x100u * rawData[7]); var uid = rawData[8] + (0x100u * rawData[9]); var gid = rawData[10] + (0x100u * rawData[11]); var nlink = rawData[12] + (0x100u * rawData[13]); var rdev = rawData[14] + (0x100u * rawData[15]); var mtime = rawData[18] + (0x100u * rawData[19]) + (0x10000u * rawData[16]) + (0x1000000u * rawData[17]); var namesize = rawData[20] + (0x100u * rawData[21]); var filesize = rawData[24] + (0x100u * rawData[25]) + (0x10000u * rawData[22]) + (0x1000000u * rawData[23]); // CPIO appends an extra NUL character if the namesize is odd int rawNameSize = (int)namesize; if ((rawNameSize & 1) == 1) { rawNameSize++; } byte[] rawName = new byte[rawNameSize]; if (rawNameSize != reader.Read(rawName, 0, rawNameSize)) { throw new FormatException("Not enough data for the name for CPIO binary header"); } var name = AsciiData.FromNulPaddedString(rawName, 0, rawNameSize); List<byte> allData = new List<byte>(); allData.AddRange(rawData); allData.AddRange(rawName); int allDataSize = allData.Count; var chunkName = ChunkNames.MakeHeaderChunkName(name); var headerItem = ItemDefinition.FromByteSpan(allData.ToArray()).WithName(chunkName); if ((name.CompareTo(TrailerFileName) == 0) && (filesize == 0) && (uid == 0)) { TrailerDetected = true; } return new HeaderDetails(headerItem, null, name, filesize); } protected override UInt64 AlignmentPadding { get => 2; } } }