Example #1
0
        private DecoderMetadataBuilder ReadDecoder()
        {
            var decoder = new DecoderMetadataBuilder();

            var mainByte = ReadByte();

            if ((mainByte & 0x80) != 0)
            {
                throw new NotImplementedException();
            }

            var idLen = (mainByte & 0x0F);

            if (idLen > 4)
            {
                throw new InvalidDataException(); // all known decoders use 4 bytes or less
            }
            int id = 0;

            for (int i = idLen - 1; i >= 0; i--)
            {
                id |= ReadByte() << (i * 8);
            }

            decoder.Method = CompressionMethod.TryDecode(id);
            if (decoder.Method.IsUndefined)
            {
                throw new InvalidDataException(); // unknown decoder
            }
            if ((mainByte & 0x10) != 0)
            {
                decoder.InputCount  = ReadNumberAsInt32();
                decoder.OutputCount = ReadNumberAsInt32();
            }
            else
            {
                decoder.InputCount  = 1;
                decoder.OutputCount = 1;
            }

            decoder.Method.CheckInputOutputCount(decoder.InputCount, decoder.OutputCount);

            decoder.InputInfo = ImmutableArray.CreateBuilder <DecoderInputMetadata>(decoder.InputCount);

            // We need to fill the array because it is not guaranteed that inputs will be connected in order.
            // No valid decoder can have Int32.MaxValue inputs so we can use this as a placeholder value to detect bugs.
            var placeholder = new DecoderInputMetadata(Int32.MaxValue, Int32.MaxValue);

            for (int i = 0; i < decoder.InputCount; i++)
            {
                decoder.InputInfo.Add(placeholder);
            }

            if ((mainByte & 0x20) != 0)
            {
                var settingsLength  = ReadNumberAsInt32();
                var settingsBuilder = ImmutableArray.CreateBuilder <byte>(settingsLength);

                for (int i = 0; i < settingsLength; i++)
                {
                    settingsBuilder.Add(ReadByte());
                }

                decoder.Settings = settingsBuilder.MoveToImmutable();
            }
            else
            {
                decoder.Settings = ImmutableArray <byte> .Empty;
            }

            return(decoder);
        }