skyscraper8/skyscraper8/Skyscraper/Text/En300468TextDecoder.cs
2025-07-05 22:26:42 +02:00

142 lines
6.7 KiB
C#

using System;
using System.Text;
using skyscraper5.Dvb;
using skyscraper5.Skyscraper.Plugins;
using skyscraper8.Skyscraper.Text;
namespace skyscraper5.Skyscraper.Text
{
public class En300468AnnexATextDecoder
{
private En300468AnnexATextDecoder()
{
Encoding.RegisterProvider(SkyscraperEncodingProvider.GetInstance());
tables = new Encoding[0x20];
tables[0x00] = Encoding.GetEncoding("dvb-iso-6937"); //ISO 6397
tables[0x01] = Encoding.GetEncoding("dvb-iso-8859-5"); //iso 8859-5
tables[0x02] = Encoding.GetEncoding("dvb-iso-8859-6"); //iso 8859-6
tables[0x03] = Encoding.GetEncoding("dvb-iso-8859-7"); //iso 8859-7
tables[0x04] = Encoding.GetEncoding("dvb-iso-8859-8"); //iso 8859-8
tables[0x05] = Encoding.GetEncoding("dvb-iso-8859-9"); //iso 8859-9
tables[0x06] = Encoding.GetEncoding("dvb-iso-8859-10"); //ISO/IEC 8859-10
tables[0x07] = Encoding.GetEncoding("dvb-iso-8859-11"); //ISO/IEC 8859-11
tables[0x09] = Encoding.GetEncoding("dvb-iso-8859-13"); //ISO/IEC 8859-13
tables[0x0a] = Encoding.GetEncoding("dvb-iso-8859-14"); //ISO/IEC 8859-14
tables[0x0b] = Encoding.GetEncoding("dvb-iso-8859-15"); //iso 8859-15
tables[0x11] = Encoding.GetEncoding("dvb-iso-10646"); //iso 10646
tables[0x12] = Encoding.GetEncoding("dvb-ksx1001-2004"); //KSX1001-2004
tables[0x13] = Encoding.GetEncoding("dvb-gb-2312-1980"); //gb-2312
tables[0x14] = Encoding.GetEncoding("dvb-big5"); //Big5 subset of ISO/IEC 10646
tables[0x15] = Encoding.GetEncoding("dvb-utf8"); //UTF-8 encoding of ISO/IEC 10646
iso8859Mapping = new Encoding[0x10];
iso8859Mapping[0x01] = Encoding.GetEncoding("dvb-iso-8859-1"); //iso 8859-1
iso8859Mapping[0x02] = Encoding.GetEncoding("dvb-iso-8859-2"); //iso 8859-2
iso8859Mapping[0x03] = Encoding.GetEncoding("dvb-iso-8859-3"); //iso 8859-3
iso8859Mapping[0x04] = Encoding.GetEncoding("dvb-iso-8859-4"); //iso 8859-4
iso8859Mapping[0x05] = Encoding.GetEncoding("dvb-iso-8859-5"); //iso 8859-5
iso8859Mapping[0x06] = Encoding.GetEncoding("dvb-iso-8859-6"); //iso 8859-6
iso8859Mapping[0x07] = Encoding.GetEncoding("dvb-iso-8859-7"); //iso 8859-7
iso8859Mapping[0x08] = Encoding.GetEncoding("dvb-iso-8859-8"); //iso 8859-8
iso8859Mapping[0x09] = Encoding.GetEncoding("dvb-iso-8859-9"); //iso 8859-9
iso8859Mapping[0x0a] = Encoding.GetEncoding("dvb-iso-8859-10"); //ISO/IEC 8859-10
iso8859Mapping[0x0b] = Encoding.GetEncoding("dvb-iso-8859-11"); //ISO/IEC 8859-11
iso8859Mapping[0x0c] = Encoding.GetEncoding("dvb-iso-8859-12"); //ISO/IEC 8859-12
iso8859Mapping[0x0d] = Encoding.GetEncoding("dvb-iso-8859-13"); //ISO/IEC 8859-13
iso8859Mapping[0x0e] = Encoding.GetEncoding("dvb-iso-8859-14"); //ISO/IEC 8859-14
iso8859Mapping[0x0f] = Encoding.GetEncoding("dvb-iso-8859-15"); //iso 8859-15
}
private static En300468AnnexATextDecoder _instance;
private static Encoding[] tables;
private static Encoding[] iso8859Mapping;
private static TextDecoder[] _textDecoders;
public static En300468AnnexATextDecoder GetInstance()
{
if (_instance == null)
_instance = new En300468AnnexATextDecoder();
return _instance;
}
public string Decode(byte[] buffer, int offset, int length)
{
byte[] copy = new byte[length];
Array.Copy(buffer, offset, copy, 0, length);
return Decode(copy);
}
private Encoding lastUsedEncoding;
public string Decode(byte[] buffer)
{
if (buffer.Length == 0)
return null;
if (buffer.Length == 1)
return null;
if (buffer[0] >= 0x20)
{
lastUsedEncoding = tables[0];
return tables[0].GetString(buffer, 0, buffer.Length);
}
else if ((buffer[0] >= 0x01 && buffer[0] <= 0x07) || (buffer[0] >= 0x09 && buffer[0] <= 0x0b) || (buffer[0] >= 0x11 && buffer[0] <= 0x14))
{
lastUsedEncoding = tables[buffer[0]];
return tables[buffer[0]].GetString(buffer, 1, buffer.Length - 1);
}
else if (buffer[0] == 0x10)
{
if (buffer.Length == 2)
return null;
ushort sb = buffer[1];
ushort tb = buffer[2];
if (sb != 0x00)
throw new NotImplementedException("reserved");
if (tb >= 0x10)
throw new NotImplementedException("reserved");
lastUsedEncoding = iso8859Mapping[tb];
return iso8859Mapping[tb].GetString(buffer, 3, buffer.Length - 3);
}
else if (buffer[0] == 0x15)
{
lastUsedEncoding = tables[0x15];
return tables[0x15].GetString(buffer, 1, buffer.Length - 1);
}
else if (buffer[0] == 0x1f)
{
//It shall be coded according to ETSI TS 101 162
if (_textDecoders == null)
_textDecoders = PluginManager.GetInstance().GetTextDecoders();
TextDecoder matchingTextDecoder = _textDecoders[buffer[1]];
if (matchingTextDecoder == null)
{
throw new TextException(String.Format("No decoder for Encoding type ID 0x{0:X2}", buffer[1]));
}
return matchingTextDecoder.Decode(buffer);
}
else if (buffer[0] >= 0x16 && buffer[0] <= 0x1e)
{
return null; //ETSI EN 300468, Table A.3 "reserved for future use", therefore invalid.
}
if (lastUsedEncoding != null)
{
return lastUsedEncoding.GetString(buffer);
}
throw new DvbException("failed to detect encoding");
}
public byte[] Encode(string serviceName)
{
byte[] utf8buffer = Encoding.UTF8.GetBytes(serviceName);
byte[] result = new byte[utf8buffer.Length + 1];
result[0] = 0x15;
Array.Copy(utf8buffer, 0, result, 1, utf8buffer.Length);
return result;
}
}
}