/// <summary>
        /// Constructor
        /// </summary>
        /// <param name="resourceProvider">Owner</param>
        /// <param name="resourceInfo">Resource info</param>
        /// <param name="span">Span</param>
        /// <param name="lengthPosition">Position of 32-bit content length which immediately follows the 7-bit encoded type code</param>
        public MultiResourceArrayDataHeaderData(DotNetMultiFileResources resourceProvider, MultiResourceInfo resourceInfo, HexBufferSpan span, HexPosition lengthPosition)
            : base(resourceProvider, resourceInfo, span)
        {
            var typeCodeSpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(span.Start, lengthPosition));

            TypeCode      = new StructField <ResourceTypeCodeData>("TypeCode", ResourceTypeCodeData.Create(typeCodeSpan));
            ContentLength = new StructField <UInt32Data>("ContentLength", new UInt32Data(span.Buffer, lengthPosition));
            var arraySpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(lengthPosition + 4, span.End));

            Content = new StructField <VirtualArrayData <ByteData> >("Content", ArrayData.CreateVirtualByteArray(arraySpan));
            Fields  = new BufferField[] {
                TypeCode,
                ContentLength,
                Content,
            };
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="resourceProvider">Owner</param>
        /// <param name="resourceInfo">Resource info</param>
        /// <param name="span">Span</param>
        /// <param name="lengthSpan">Span of 7-bit encoded string length</param>
        /// <param name="stringSpan">Span of string data (UTF-8)</param>
        public MultiResourceStringDataHeaderData(DotNetMultiFileResources resourceProvider, MultiResourceInfo resourceInfo, HexBufferSpan span, HexSpan lengthSpan, HexSpan stringSpan)
            : base(resourceProvider, resourceInfo, span)
        {
            if (!span.Span.Contains(lengthSpan))
            {
                throw new ArgumentOutOfRangeException(nameof(lengthSpan));
            }
            if (!span.Span.Contains(stringSpan))
            {
                throw new ArgumentOutOfRangeException(nameof(stringSpan));
            }
            if (lengthSpan.End != stringSpan.Start)
            {
                throw new ArgumentOutOfRangeException(nameof(stringSpan));
            }
            var typeCodeSpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(span.Start, lengthSpan.Start));

            TypeCode = new StructField <ResourceTypeCodeData>("TypeCode", ResourceTypeCodeData.Create(typeCodeSpan));
            Content  = new StructField <Bit7EncodedStringData>("Content", new Bit7EncodedStringData(span.Buffer, lengthSpan, stringSpan, Encoding.UTF8));
            Fields   = new BufferField[] {
                TypeCode,
                Content,
            };
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="resourceProvider">Owner</param>
        /// <param name="resourceInfo">Resource info</param>
        /// <param name="span">Span</param>
        /// <param name="dataPosition">Position of data which immediately follows the 7-bit encoded type code</param>
        public MultiResourceSimplDataHeaderData(DotNetMultiFileResources resourceProvider, MultiResourceInfo resourceInfo, HexBufferSpan span, HexPosition dataPosition)
            : base(resourceProvider, resourceInfo, span)
        {
            // Don't use Contains() since data length could be 0
            if (dataPosition < span.Start || dataPosition > span.End)
            {
                throw new ArgumentOutOfRangeException(nameof(dataPosition));
            }
            var typeCodeSpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(span.Start, dataPosition));

            TypeCode = new StructField <ResourceTypeCodeData>("TypeCode", ResourceTypeCodeData.Create(typeCodeSpan));

            var pos      = typeCodeSpan.Span.Start;
            var typeCode = (ResourceTypeCode)(Utils.Read7BitEncodedInt32(span.Buffer, ref pos) ?? -1);
            var dataSpan = new HexBufferSpan(span.Buffer, HexSpan.FromBounds(dataPosition, span.End));

            switch (typeCode)
            {
            case ResourceTypeCode.String:
                Debug.Fail($"Use {nameof(MultiResourceStringDataHeaderData)}");
                goto default;

            case ResourceTypeCode.ByteArray:
            case ResourceTypeCode.Stream:
                Debug.Fail($"Use {nameof(MultiResourceArrayDataHeaderData)}");
                goto default;

            case ResourceTypeCode.Boolean:
                Content = new StructField <BooleanData>("Content", new BooleanData(dataSpan));
                break;

            case ResourceTypeCode.Char:
                Content = new StructField <CharData>("Content", new CharData(dataSpan));
                break;

            case ResourceTypeCode.Byte:
                Content = new StructField <ByteData>("Content", new ByteData(dataSpan));
                break;

            case ResourceTypeCode.SByte:
                Content = new StructField <SByteData>("Content", new SByteData(dataSpan));
                break;

            case ResourceTypeCode.Int16:
                Content = new StructField <Int16Data>("Content", new Int16Data(dataSpan));
                break;

            case ResourceTypeCode.UInt16:
                Content = new StructField <UInt16Data>("Content", new UInt16Data(dataSpan));
                break;

            case ResourceTypeCode.Int32:
                Content = new StructField <Int32Data>("Content", new Int32Data(dataSpan));
                break;

            case ResourceTypeCode.UInt32:
                Content = new StructField <UInt32Data>("Content", new UInt32Data(dataSpan));
                break;

            case ResourceTypeCode.Int64:
                Content = new StructField <Int64Data>("Content", new Int64Data(dataSpan));
                break;

            case ResourceTypeCode.UInt64:
                Content = new StructField <UInt64Data>("Content", new UInt64Data(dataSpan));
                break;

            case ResourceTypeCode.Single:
                Content = new StructField <SingleData>("Content", new SingleData(dataSpan));
                break;

            case ResourceTypeCode.Double:
                Content = new StructField <DoubleData>("Content", new DoubleData(dataSpan));
                break;

            case ResourceTypeCode.Decimal:
                Content = new StructField <DecimalData>("Content", new DecimalData(dataSpan));
                break;

            case ResourceTypeCode.DateTime:
                Content = new StructField <DateTimeData>("Content", new DateTimeData(dataSpan));
                break;

            case ResourceTypeCode.TimeSpan:
                Content = new StructField <TimeSpanData>("Content", new TimeSpanData(dataSpan));
                break;

            case ResourceTypeCode.Null:
            default:
                Content = new StructField <VirtualArrayData <ByteData> >("Content", ArrayData.CreateVirtualByteArray(dataSpan));
                break;
            }

            Fields = new BufferField[] {
                TypeCode,
                Content,
            };
        }