2025-06-21 03:51:58 +02:00

109 lines
3.3 KiB
C#

using skyscraper5.Skyscraper.IO;
using skyscraper8.DvbNip;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace skyscraper8.Ietf.FLUTE
{
internal class LctHeader
{
/// <summary>
///
/// </summary>
/// <param name="headerBuffer">A buffer that contains an LCT Header starting from the first byte of the Congestion Control Information</param>
/// <param name="c">Congestion control flag</param>
/// <param name="s">Transport Session Identifier flag</param>
/// <param name="o">Transport Object Identifier flag</param>
/// <param name="h">Half-word flag</param>
/// <exception cref="NotSupportedException"></exception>
public LctHeader(byte[] headerBuffer, int c, bool sFlag, int o, bool hFlag)
{
int s = sFlag ? 1 : 0;
int h = hFlag ? 1 : 0;
MemoryStream ms = new MemoryStream(headerBuffer, false);
int cciLength = 32 * (c + 1);
int tsiLength = 32 * s + 16 * h;
int toiLength = 32 * o + 16 * h;
CongestionControlInformation = ReadField(ms, cciLength);
TransportSessionIdentifier = ReadField(ms, tsiLength);
TransportObjectIdentifier = ReadField(ms, toiLength);
while (ms.GetAvailableBytes() >= 1)
{
byte extensionId = ms.ReadUInt8();
if (extensionId >= 128)
{
ms.Position--;
uint fixedHeaderExtension = ms.ReadUInt32BE();
switch (extensionId)
{
case 192:
this.FdtInstanceId = new FdtInstanceHeader(fixedHeaderExtension);
break;
case 193:
this.ContentEncoding = new ContentEncodingOfFdtInstance(fixedHeaderExtension);
break;
default:
throw new NotImplementedException(String.Format("LCT Header Extension {0}", extensionId));
}
}
else
{
uint headerExtensionLength = ms.ReadUInt8();
headerExtensionLength *= 4;
if (headerExtensionLength >= 2)
headerExtensionLength -= 2;
byte[] extensionBuffer = ms.ReadBytes(headerExtensionLength);
switch(extensionId)
{
case 0:
break;
case 2:
this.TimeExtenstion = new TimeHeaderExtension(extensionBuffer);
break;
case 64:
this.FecObjectTransmissionInformation = new FecObjectTransmissionInformation(extensionBuffer);
break;
case 68:
this.NipActualCarrierInformation = new NipActualCarrierInformation(extensionBuffer);
break;
default:
throw new NotImplementedException(String.Format("LCT Header Extension {0}", extensionId));
}
}
}
}
private ulong ReadField(Stream stream, int bits)
{
switch(bits)
{
case 16:
return stream.ReadUInt16BE();
case 32:
return stream.ReadUInt32BE();
case 48:
return stream.ReadUInt48BE();
case 64:
return stream.ReadUInt64BE();
default:
throw new NotImplementedException(String.Format("{0} bits.", bits));
}
}
public ulong CongestionControlInformation { get; private set; }
public ulong TransportSessionIdentifier { get; }
public ulong TransportObjectIdentifier { get; }
public FdtInstanceHeader FdtInstanceId { get; }
public NipActualCarrierInformation NipActualCarrierInformation { get; }
public FecObjectTransmissionInformation FecObjectTransmissionInformation { get; }
public TimeHeaderExtension TimeExtenstion { get; }
public ContentEncodingOfFdtInstance ContentEncoding { get; }
}
}