public UnicodeNameAndOffsetData(ResourceInfo owner, Bit7String bit7String)
     : base(DataKind.UnicodeNameAndOffset, HexSpan.FromBounds(bit7String.FullSpan.Start, bit7String.FullSpan.End + 4))
 {
     Owner      = owner;
     Bit7String = bit7String;
 }
        static DotNetMultiFileResourcesImpl?TryReadCore(HexBufferFile file)
        {
            if (file is null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (file.Span.Length < 0x1C)
            {
                return(null);
            }
            var buffer = file.Buffer;
            var pos    = file.Span.Start;

            if (buffer.ReadUInt32(pos) != 0xBEEFCACE)
            {
                return(null);
            }

            int resMgrHeaderVersion = buffer.ReadInt32(pos + 4);
            int headerSize          = buffer.ReadInt32(pos + 8);

            if (resMgrHeaderVersion < 0 || headerSize < 0)
            {
                return(null);
            }
            pos += 0xC;

            Bit7String?resourceTypeSpan    = null;
            Bit7String?resourceSetTypeSpan = null;

            if (resMgrHeaderVersion > 1)
            {
                pos += headerSize;
            }
            else
            {
                resourceTypeSpan    = ReadBit7String(buffer, ref pos, file.Span.End);
                resourceSetTypeSpan = ReadBit7String(buffer, ref pos, file.Span.End);
                if (resourceTypeSpan is null || resourceSetTypeSpan is null)
                {
                    return(null);
                }
                var resourceType = Encoding.UTF8.GetString(buffer.ReadBytes(resourceTypeSpan.Value.StringSpan));
                if (!Regex.IsMatch(resourceType, @"^System\.Resources\.ResourceReader,\s*mscorlib,"))
                {
                    return(null);
                }
            }

            var versionPosition = pos;

            if (pos + 0x0C > file.Span.End)
            {
                return(null);
            }
            uint version = buffer.ReadUInt32(pos);

            if (version != 2)
            {
                return(null);               //TODO: Support version 1
            }
            int numResources = buffer.ReadInt32(pos + 4);
            int numTypes     = buffer.ReadInt32(pos + 8);

            if (numResources < 0 || numTypes < 0)
            {
                return(null);
            }
            pos += 0x0C;
            var typeNames = new Bit7String[numTypes];

            for (int i = 0; i < typeNames.Length; i++)
            {
                var info = ReadBit7String(buffer, ref pos, file.Span.End);
                if (info is null)
                {
                    return(null);
                }
                typeNames[i] = info.Value;
            }

            var paddingStart = pos;

            pos = file.AlignUp(pos, 8);
            var paddingSpan = HexSpan.FromBounds(paddingStart, pos);

            if (pos + (ulong)numResources * 8 + 4 > file.Span.End)
            {
                return(null);
            }
            pos += (ulong)numResources * 8;
            int dataSectionOffset = buffer.ReadInt32(pos);

            pos += 4;
            if (dataSectionOffset < 0 || dataSectionOffset < (pos - file.Span.Start))
            {
                return(null);
            }
            // Use > and not >= in case it's an empty resource
            if (dataSectionOffset > file.Span.Length)
            {
                return(null);
            }
            var dataSectionPosition = file.Span.Start + dataSectionOffset;
            var nameSectionPosition = pos;

            return(new DotNetMultiFileResourcesImpl(file, resourceTypeSpan, resourceSetTypeSpan, versionPosition, paddingSpan, typeNames, numResources, dataSectionPosition, nameSectionPosition));
        }
 public StringResData(ResourceTypeCode typeCode, HexSpan codeSpan, HexSpan dataSpan, Bit7String utf8StringValue)
     : base(typeCode, codeSpan, dataSpan, utf8StringValue.StringSpan) => Utf8StringValue = utf8StringValue;
 public TypeResData(ResourceTypeCode typeCode, HexSpan codeSpan, HexSpan dataSpan, Bit7String utf8TypeName)
     : base(typeCode, codeSpan, dataSpan, dataSpan) => Utf8TypeName = utf8TypeName;
 public ResourceInfo(int index, Bit7String unicodeName, HexPosition dataPos)
 {
     Index       = index;
     UnicodeName = unicodeName;
     DataStart   = dataPos;
 }