Exemple #1
0
        public override ILoadedImage Load(Address?addrLoad)
        {
            var rdr = new ByteImageReader(RawImage);

            ReadHeader(rdr);
            var archive = new ArArchive(this.ImageLocation);

            ReadFiles(rdr, archive);
            return(archive);
        }
Exemple #2
0
 private void ReadFiles(ByteImageReader rdr, ArArchive archive)
 {
     for (; ;)
     {
         var header = ArFileHeader.Load(rdr);
         if (header == null)
         {
             return;
         }
         ReadFile(header, rdr, archive);
     }
 }
Exemple #3
0
        private void ReadFile(ArFileHeader fileHeader, ByteImageReader rdr, ArArchive archive)
        {
            if (!int.TryParse(fileHeader.FileSize, out int dataSize))
            {
                throw new BadImageFormatException("Invalid archive file header.");
            }
            if (dataSize + rdr.Offset > rdr.Bytes.Length)
            {
                throw new BadImageFormatException("The archive file is corrupt.");
            }

            string name = fileHeader.Name;

            if (name.StartsWith("// "))
            {
                throw new NotImplementedException("Extended file names not implemented yet.");
            }
            else if (name.StartsWith("/ ") || name.StartsWith("__.SYMDEF"))
            {
                // System V symbol lookup table.
                var symbolData = rdr.ReadBytes(dataSize);
                ReadSymbolTable(symbolData);
                return;
            }
            else if (name.StartsWith("#1/ "))
            {
                // File name length follows #1/ as decimal digits.
                // This variant is used by Mac and some versions of BSD.
                var  fileNameLength = Convert.ToInt32(name + 3);
                long fileDataOffset = rdr.Offset + fileNameLength;
                name = Encoding.ASCII.GetString(rdr.ReadBytes(fileNameLength));
                if (dataSize > fileNameLength)
                {
                    // The length of the name is included in the dataSize.
                    dataSize -= fileNameLength;
                }
                rdr.Offset = fileDataOffset;
            }
            else
            {
                // Ordinary short name
                char[] charsToTrim = { '/', ' ' };
                name = name.TrimEnd(charsToTrim);
            }

            archive.AddFile(name, (a, p, name) => new ArFile(a, p, name, rdr, rdr.Offset, dataSize));
            rdr.Offset += dataSize;
            AlignReader(rdr);
        }