mirror of
https://github.com/PredatH0r/ChanSort.git
synced 2026-05-07 12:27:49 +02:00
- moved all files to a "source" subdirectory to tidy up the GitHub project page
- started to write a readme.md
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{68DA8072-3A29-4076-9F64-D66F38349585}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ChanSort.Loader.Panasonic</RootNamespace>
|
||||
<AssemblyName>ChanSort.Loader.Panasonic</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
|
||||
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SQLite, Version=1.0.84.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\DLL\System.Data.SQLite.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DbChannel.cs" />
|
||||
<Compile Include="Serializer.cs" />
|
||||
<Compile Include="SerializerPlugin.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Service Include="{94E38DFF-614B-4cbd-B67C-F211BB35CE8B}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ChanSort.Api\ChanSort.Api.csproj">
|
||||
<Project>{DCCFFA08-472B-4D17-BB90-8F513FC01392}</Project>
|
||||
<Name>ChanSort.Api</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
238
source/ChanSort.Loader.Panasonic/DbChannel.cs
Normal file
238
source/ChanSort.Loader.Panasonic/DbChannel.cs
Normal file
@@ -0,0 +1,238 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SQLite;
|
||||
using System.Text;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Panasonic
|
||||
{
|
||||
internal class DbChannel : ChannelInfo
|
||||
{
|
||||
internal int Bits;
|
||||
internal byte[] RawName;
|
||||
|
||||
#region ctor()
|
||||
internal DbChannel(SQLiteDataReader r, IDictionary<string, int> field, DataRoot dataRoot, Encoding encoding)
|
||||
{
|
||||
this.RecordIndex = r.GetInt32(field["rowid"]);
|
||||
this.RecordOrder = r.GetInt32(field["major_channel"]);
|
||||
this.OldProgramNr = r.GetInt32(field["major_channel"]);
|
||||
int ntype = r.GetInt32(field["ntype"]);
|
||||
if (ntype == 1)
|
||||
{
|
||||
this.SignalSource |= SignalSource.DvbS;
|
||||
if (r.GetInt32(field["ya_svcid"]) >= 0)
|
||||
this.SignalSource |= SignalSource.Freesat;
|
||||
}
|
||||
else if (ntype == 2)
|
||||
this.SignalSource |= SignalSource.DvbT;
|
||||
else if (ntype == 3)
|
||||
this.SignalSource |= SignalSource.DvbC;
|
||||
else if (ntype == 10)
|
||||
this.SignalSource |= SignalSource.AnalogT | SignalSource.Tv;
|
||||
else if (ntype == 14)
|
||||
this.SignalSource |= SignalSource.AnalogC | SignalSource.Tv;
|
||||
else if (ntype == 15)
|
||||
this.SignalSource |= SignalSource.SatIP;
|
||||
|
||||
byte[] buffer = new byte[1000];
|
||||
var len = r.GetBytes(field["delivery"], 0, buffer, 0, 1000);
|
||||
this.AddDebug(buffer, 0, (int) len);
|
||||
|
||||
this.Skip = r.GetInt32(field["skip"]) != 0;
|
||||
this.Encrypted = r.GetInt32(field["free_CA_mode"]) != 0;
|
||||
this.Lock = r.GetInt32(field["child_lock"]) != 0;
|
||||
this.ParseFavorites(r, field);
|
||||
this.ReadNamesWithEncodingDetection(r, field, encoding);
|
||||
|
||||
if (ntype == 10 || ntype == 14)
|
||||
this.ReadAnalogData(r, field);
|
||||
else
|
||||
this.ReadDvbData(r, field, dataRoot, buffer);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ParseFavorites
|
||||
private void ParseFavorites(SQLiteDataReader r, IDictionary<string, int> field)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int favIndex = r.GetInt32(field["profile" + (i + 1) + "index"]);
|
||||
if (favIndex > 0)
|
||||
{
|
||||
this.Favorites |= (Favorites) (1 << i);
|
||||
this.FavIndex[i] = favIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadAnalogData()
|
||||
private void ReadAnalogData(SQLiteDataReader r, IDictionary<string, int> field)
|
||||
{
|
||||
this.FreqInMhz = r.IsDBNull(field["freq"]) ? 0 : (decimal)r.GetInt32(field["freq"]) / 1000;
|
||||
this.ChannelOrTransponder = Tools.GetAnalogChannelNumber((int)this.FreqInMhz);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadDvbData()
|
||||
protected void ReadDvbData(SQLiteDataReader r, IDictionary<string, int> field, DataRoot dataRoot, byte[] delivery)
|
||||
{
|
||||
int stype = r.GetInt32(field["stype"]);
|
||||
this.SignalSource |= LookupData.Instance.IsRadioOrTv(stype);
|
||||
this.ServiceType = stype;
|
||||
|
||||
int freq = r.GetInt32(field["freq"]);
|
||||
if ((this.SignalSource & SignalSource.Sat) != 0)
|
||||
{
|
||||
// ReSharper disable PossibleLossOfFraction
|
||||
this.FreqInMhz = freq/10;
|
||||
// ReSharper restore PossibleLossOfFraction
|
||||
int satId = r.GetInt32(field["physical_ch"]) >> 12;
|
||||
var sat = dataRoot.Satellites.TryGet(satId);
|
||||
if (sat != null)
|
||||
{
|
||||
this.Satellite = sat.Name;
|
||||
this.SatPosition = sat.OrbitalPosition;
|
||||
}
|
||||
if (delivery.Length >= 7)
|
||||
{
|
||||
this.SymbolRate = (delivery[5] >> 4)*10000 + (delivery[5] & 0x0F)*1000 +
|
||||
(delivery[6] >> 4)*100 + (delivery[6] & 0x0F)*10;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
freq /= 1000;
|
||||
this.FreqInMhz = freq;
|
||||
this.ChannelOrTransponder = LookupData.Instance.GetDvbtTransponder(freq).ToString();
|
||||
this.Satellite = (this.SignalSource & SignalSource.Antenna) != 0 ? "DVB-T" : "DVB-C";
|
||||
}
|
||||
|
||||
this.OriginalNetworkId = r.GetInt32(field["onid"]);
|
||||
this.TransportStreamId = r.GetInt32(field["tsid"]);
|
||||
this.ServiceId = r.GetInt32(field["sid"]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadNamesWithEncodingDetection()
|
||||
/// <summary>
|
||||
/// Character encoding is a mess here. Code pages mixed with UTF-8 and raw data
|
||||
/// </summary>
|
||||
private void ReadNamesWithEncodingDetection(SQLiteDataReader r, IDictionary<string, int> field, Encoding encoding)
|
||||
{
|
||||
byte[] buffer = new byte[100];
|
||||
int len = (int)r.GetBytes(field["sname"], 0, buffer, 0, buffer.Length);
|
||||
int end = Array.IndexOf<byte>(buffer, 0, 0, len);
|
||||
if (end >= 0)
|
||||
len = end;
|
||||
this.RawName = new byte[len];
|
||||
Array.Copy(buffer, 0, this.RawName, 0, len);
|
||||
this.ChangeEncoding(encoding);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ChangeEncoding()
|
||||
public override void ChangeEncoding(Encoding encoding)
|
||||
{
|
||||
// the encoding of channel names is a complete mess:
|
||||
// it can be UTF-8
|
||||
// it can be as specified by the DVB-encoding with a valid code page selector byte
|
||||
// it can have a DVB-encoded code page selector, but ignores the CP and use UTF-8 regardless
|
||||
// it can be code page encoded without any clue to what the code page is
|
||||
// it can have DVB-control characters inside an UTF-8 stream
|
||||
|
||||
if (RawName.Length == 0)
|
||||
return;
|
||||
|
||||
int startOffset;
|
||||
int bytesPerChar;
|
||||
if (!GetRecommendedEncoding(ref encoding, out startOffset, out bytesPerChar))
|
||||
return;
|
||||
|
||||
// single byte code pages might have UTF-8 code mixed in, so we have to parse it manually
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = startOffset; i < this.RawName.Length; i+=bytesPerChar)
|
||||
{
|
||||
byte c = this.RawName[i];
|
||||
byte c2 = i + 1 < this.RawName.Length ? this.RawName[i + 1] : (byte)0;
|
||||
if (c < 0xA0)
|
||||
sb.Append((char)c);
|
||||
else if (bytesPerChar == 1 && c >= 0xC0 && c <= 0xDF && c2 >= 0x80 && c2 <= 0xBF) // 2 byte UTF-8
|
||||
{
|
||||
sb.Append((char)(((c & 0x1F) << 6) | (c2 & 0x3F)));
|
||||
++i;
|
||||
}
|
||||
else
|
||||
sb.Append(encoding.GetString(this.RawName, i, bytesPerChar));
|
||||
}
|
||||
|
||||
string longName, shortName;
|
||||
this.GetChannelNames(sb.ToString(), out longName, out shortName);
|
||||
this.Name = longName;
|
||||
this.ShortName = shortName;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetRecommendedEncoding()
|
||||
private bool GetRecommendedEncoding(ref Encoding encoding, out int startOffset, out int bytesPerChar)
|
||||
{
|
||||
startOffset = 0;
|
||||
bytesPerChar = 1;
|
||||
if (RawName[0] < 0x10) // single byte character sets
|
||||
{
|
||||
encoding = DvbStringDecoder.GetEncoding(RawName[0]);
|
||||
startOffset = 1;
|
||||
}
|
||||
else if (RawName[0] == 0x10) // prefix for 16 bit code page ID with single byte character sets
|
||||
{
|
||||
if (RawName.Length < 3) return false;
|
||||
encoding = DvbStringDecoder.GetEncoding(0x100000 + RawName[1]*256 + RawName[2]);
|
||||
startOffset = 3;
|
||||
}
|
||||
else if (RawName[0] == 0x15) // UTF-8
|
||||
{
|
||||
encoding = Encoding.UTF8;
|
||||
startOffset = 1;
|
||||
}
|
||||
else if (RawName[0] < 0x20) // various 2-byte character sets
|
||||
{
|
||||
encoding = DvbStringDecoder.GetEncoding(RawName[0]);
|
||||
startOffset = 1;
|
||||
bytesPerChar = 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetChannelNames()
|
||||
private void GetChannelNames(string name, out string longName, out string shortName)
|
||||
{
|
||||
StringBuilder sbLong = new StringBuilder();
|
||||
StringBuilder sbShort = new StringBuilder();
|
||||
|
||||
bool inShort = false;
|
||||
foreach (char c in name)
|
||||
{
|
||||
if (c < 0x20)
|
||||
continue;
|
||||
if (c == 0x86 || c == '\uE086')
|
||||
inShort = true;
|
||||
else if (c == 0x87 || c == '\uE087')
|
||||
inShort = false;
|
||||
if (c >= 0x80 && c <= 0x9F || c>='\uE080' && c<='\uE09F')
|
||||
continue;
|
||||
|
||||
if (inShort)
|
||||
sbShort.Append(c);
|
||||
sbLong.Append(c);
|
||||
}
|
||||
|
||||
longName = sbLong.ToString();
|
||||
shortName = sbShort.ToString();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
36
source/ChanSort.Loader.Panasonic/Properties/AssemblyInfo.cs
Normal file
36
source/ChanSort.Loader.Panasonic/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("ChanSort.Loader.Panasonic")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ChanSort.Loader.Panasonic")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("bcd581a8-8959-404c-b7a8-e43f512eec03")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
705
source/ChanSort.Loader.Panasonic/Serializer.cs
Normal file
705
source/ChanSort.Loader.Panasonic/Serializer.cs
Normal file
@@ -0,0 +1,705 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SQLite;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Panasonic
|
||||
{
|
||||
class Serializer : SerializerBase
|
||||
{
|
||||
private const string ERR_FileFormatOrEncryption = "File uses an unknown format or encryption";
|
||||
private static readonly int[] headerCypherTable;
|
||||
private readonly ChannelList avbtChannels = new ChannelList(SignalSource.AnalogT | SignalSource.Tv | SignalSource.Radio, "Analog Antenna");
|
||||
private readonly ChannelList avbcChannels = new ChannelList(SignalSource.AnalogC | SignalSource.Tv | SignalSource.Radio, "Analog Cable");
|
||||
private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT | SignalSource.Tv | SignalSource.Radio, "DVB-T");
|
||||
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC | SignalSource.Tv | SignalSource.Radio, "DVB-C");
|
||||
private readonly ChannelList dvbsChannels = new ChannelList(SignalSource.DvbS | SignalSource.Tv | SignalSource.Radio, "DVB-S");
|
||||
private readonly ChannelList satipChannels = new ChannelList(SignalSource.SatIP | SignalSource.Tv | SignalSource.Radio, "SAT>IP");
|
||||
private readonly ChannelList freesatChannels = new ChannelList(SignalSource.DvbS | SignalSource.Freesat | SignalSource.Tv | SignalSource.Radio, "Freesat");
|
||||
|
||||
private string workFile;
|
||||
private CypherMode cypherMode;
|
||||
private byte[] fileHeader = new byte[0];
|
||||
private int dbSizeOffset;
|
||||
private bool littleEndianByteOrder;
|
||||
private string charEncoding;
|
||||
|
||||
enum CypherMode
|
||||
{
|
||||
None,
|
||||
HeaderAndChecksum,
|
||||
Encryption,
|
||||
Unknown
|
||||
}
|
||||
|
||||
|
||||
#region static ctor / headerCypherTable
|
||||
static Serializer()
|
||||
{
|
||||
headerCypherTable = new[]
|
||||
{
|
||||
0,
|
||||
79764919,
|
||||
159529838,
|
||||
222504665,
|
||||
319059676,
|
||||
398814059,
|
||||
445009330,
|
||||
507990021,
|
||||
638119352,
|
||||
583659535,
|
||||
797628118,
|
||||
726387553,
|
||||
890018660,
|
||||
835552979,
|
||||
1015980042,
|
||||
944750013,
|
||||
1276238704,
|
||||
1221641927,
|
||||
1167319070,
|
||||
1095957929,
|
||||
1595256236,
|
||||
1540665371,
|
||||
1452775106,
|
||||
1381403509,
|
||||
1780037320,
|
||||
1859660671,
|
||||
1671105958,
|
||||
1733955601,
|
||||
2031960084,
|
||||
2111593891,
|
||||
1889500026,
|
||||
1952343757,
|
||||
-1742489888,
|
||||
-1662866601,
|
||||
-1851683442,
|
||||
-1788833735,
|
||||
-1960329156,
|
||||
-1880695413,
|
||||
-2103051438,
|
||||
-2040207643,
|
||||
-1104454824,
|
||||
-1159051537,
|
||||
-1213636554,
|
||||
-1284997759,
|
||||
-1389417084,
|
||||
-1444007885,
|
||||
-1532160278,
|
||||
-1603531939,
|
||||
-734892656,
|
||||
-789352409,
|
||||
-575645954,
|
||||
-646886583,
|
||||
-952755380,
|
||||
-1007220997,
|
||||
-827056094,
|
||||
-898286187,
|
||||
-231047128,
|
||||
-151282273,
|
||||
-71779514,
|
||||
-8804623,
|
||||
-515967244,
|
||||
-436212925,
|
||||
-390279782,
|
||||
-327299027,
|
||||
881225847,
|
||||
809987520,
|
||||
1023691545,
|
||||
969234094,
|
||||
662832811,
|
||||
591600412,
|
||||
771767749,
|
||||
717299826,
|
||||
311336399,
|
||||
374308984,
|
||||
453813921,
|
||||
533576470,
|
||||
25881363,
|
||||
88864420,
|
||||
134795389,
|
||||
214552010,
|
||||
2023205639,
|
||||
2086057648,
|
||||
1897238633,
|
||||
1976864222,
|
||||
1804852699,
|
||||
1867694188,
|
||||
1645340341,
|
||||
1724971778,
|
||||
1587496639,
|
||||
1516133128,
|
||||
1461550545,
|
||||
1406951526,
|
||||
1302016099,
|
||||
1230646740,
|
||||
1142491917,
|
||||
1087903418,
|
||||
-1398421865,
|
||||
-1469785312,
|
||||
-1524105735,
|
||||
-1578704818,
|
||||
-1079922613,
|
||||
-1151291908,
|
||||
-1239184603,
|
||||
-1293773166,
|
||||
-1968362705,
|
||||
-1905510760,
|
||||
-2094067647,
|
||||
-2014441994,
|
||||
-1716953613,
|
||||
-1654112188,
|
||||
-1876203875,
|
||||
-1796572374,
|
||||
-525066777,
|
||||
-462094256,
|
||||
-382327159,
|
||||
-302564546,
|
||||
-206542021,
|
||||
-143559028,
|
||||
-97365931,
|
||||
-17609246,
|
||||
-960696225,
|
||||
-1031934488,
|
||||
-817968335,
|
||||
-872425850,
|
||||
-709327229,
|
||||
-780559564,
|
||||
-600130067,
|
||||
-654598054,
|
||||
1762451694,
|
||||
1842216281,
|
||||
1619975040,
|
||||
1682949687,
|
||||
2047383090,
|
||||
2127137669,
|
||||
1938468188,
|
||||
2001449195,
|
||||
1325665622,
|
||||
1271206113,
|
||||
1183200824,
|
||||
1111960463,
|
||||
1543535498,
|
||||
1489069629,
|
||||
1434599652,
|
||||
1363369299,
|
||||
622672798,
|
||||
568075817,
|
||||
748617968,
|
||||
677256519,
|
||||
907627842,
|
||||
853037301,
|
||||
1067152940,
|
||||
995781531,
|
||||
51762726,
|
||||
131386257,
|
||||
177728840,
|
||||
240578815,
|
||||
269590778,
|
||||
349224269,
|
||||
429104020,
|
||||
491947555,
|
||||
-248556018,
|
||||
-168932423,
|
||||
-122852000,
|
||||
-60002089,
|
||||
-500490030,
|
||||
-420856475,
|
||||
-341238852,
|
||||
-278395381,
|
||||
-685261898,
|
||||
-739858943,
|
||||
-559578920,
|
||||
-630940305,
|
||||
-1004286614,
|
||||
-1058877219,
|
||||
-845023740,
|
||||
-916395085,
|
||||
-1119974018,
|
||||
-1174433591,
|
||||
-1262701040,
|
||||
-1333941337,
|
||||
-1371866206,
|
||||
-1426332139,
|
||||
-1481064244,
|
||||
-1552294533,
|
||||
-1690935098,
|
||||
-1611170447,
|
||||
-1833673816,
|
||||
-1770699233,
|
||||
-2009983462,
|
||||
-1930228819,
|
||||
-2119160460,
|
||||
-2056179517,
|
||||
1569362073,
|
||||
1498123566,
|
||||
1409854455,
|
||||
1355396672,
|
||||
1317987909,
|
||||
1246755826,
|
||||
1192025387,
|
||||
1137557660,
|
||||
2072149281,
|
||||
2135122070,
|
||||
1912620623,
|
||||
1992383480,
|
||||
1753615357,
|
||||
1816598090,
|
||||
1627664531,
|
||||
1707420964,
|
||||
295390185,
|
||||
358241886,
|
||||
404320391,
|
||||
483945776,
|
||||
43990325,
|
||||
106832002,
|
||||
186451547,
|
||||
266083308,
|
||||
932423249,
|
||||
861060070,
|
||||
1041341759,
|
||||
986742920,
|
||||
613929101,
|
||||
542559546,
|
||||
756411363,
|
||||
701822548,
|
||||
-978770311,
|
||||
-1050133554,
|
||||
-869589737,
|
||||
-924188512,
|
||||
-693284699,
|
||||
-764654318,
|
||||
-550540341,
|
||||
-605129092,
|
||||
-475935807,
|
||||
-413084042,
|
||||
-366743377,
|
||||
-287118056,
|
||||
-257573603,
|
||||
-194731862,
|
||||
-114850189,
|
||||
-35218492,
|
||||
-1984365303,
|
||||
-1921392450,
|
||||
-2143631769,
|
||||
-2063868976,
|
||||
-1698919467,
|
||||
-1635936670,
|
||||
-1824608069,
|
||||
-1744851700,
|
||||
-1347415887,
|
||||
-1418654458,
|
||||
-1506661409,
|
||||
-1561119128,
|
||||
-1129027987,
|
||||
-1200260134,
|
||||
-1254728445,
|
||||
-1309196108
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ctor()
|
||||
public Serializer(string inputFile) : base(inputFile)
|
||||
{
|
||||
DepencencyChecker.AssertVc2010RedistPackageX86Installed();
|
||||
|
||||
this.Features.ChannelNameEdit = false; // due to the chaos with binary data inside the "sname" string column, writing back a name has undesired side effects
|
||||
this.Features.CanHaveGaps = false;
|
||||
this.DataRoot.SortedFavorites = true;
|
||||
|
||||
this.DataRoot.AddChannelList(this.avbtChannels);
|
||||
this.DataRoot.AddChannelList(this.avbcChannels);
|
||||
this.DataRoot.AddChannelList(this.dvbtChannels);
|
||||
this.DataRoot.AddChannelList(this.dvbcChannels);
|
||||
this.DataRoot.AddChannelList(this.dvbsChannels);
|
||||
this.DataRoot.AddChannelList(this.satipChannels);
|
||||
this.DataRoot.AddChannelList(this.freesatChannels);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override string DisplayName { get { return "Panasonic .db/.bin Loader"; } }
|
||||
|
||||
#region Load()
|
||||
public override void Load()
|
||||
{
|
||||
this.workFile = this.GetUncypheredWorkFile();
|
||||
|
||||
this.CreateDummySatellites();
|
||||
|
||||
string channelConnString = "Data Source=" + this.workFile;
|
||||
using (var conn = new SQLiteConnection(channelConnString))
|
||||
{
|
||||
conn.Open();
|
||||
using (var cmd = conn.CreateCommand())
|
||||
{
|
||||
RepairCorruptedDatabaseImage(cmd);
|
||||
InitCharacterEncoding(cmd);
|
||||
this.ReadChannels(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetUncypheredWorkFile()
|
||||
private string GetUncypheredWorkFile()
|
||||
{
|
||||
this.cypherMode = this.GetCypherMode(this.FileName);
|
||||
if (cypherMode == CypherMode.Unknown)
|
||||
throw new FileLoadException(ERR_FileFormatOrEncryption);
|
||||
if (cypherMode == CypherMode.None)
|
||||
return this.FileName;
|
||||
|
||||
var tempFile = this.FileName + ".tmp";
|
||||
File.Delete(tempFile);
|
||||
Application.ApplicationExit += CleanTempFile;
|
||||
if (cypherMode == CypherMode.Encryption)
|
||||
this.CypherFile(this.FileName, tempFile, false);
|
||||
else
|
||||
this.RemoveHeader(this.FileName, tempFile);
|
||||
return tempFile;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetCypherMode()
|
||||
private CypherMode GetCypherMode(string file)
|
||||
{
|
||||
using (var stream = File.OpenRead(file))
|
||||
using (var rdr = new BinaryReader(stream))
|
||||
{
|
||||
uint value = (uint)rdr.ReadInt32();
|
||||
if (value == 0x694C5153) return CypherMode.None; // "SQLi"
|
||||
if (value == 0x42445350) return CypherMode.HeaderAndChecksum; // "PSDB"
|
||||
if (value == 0xA07DCB50) return CypherMode.Encryption;
|
||||
return CypherMode.Unknown;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CypherFile()
|
||||
/// <summary>
|
||||
/// XOR-based cypher which can be used to alternately crypt/decrypt data
|
||||
/// </summary>
|
||||
private void CypherFile(string input, string output, bool encrypt)
|
||||
{
|
||||
byte[] fileContent = File.ReadAllBytes(input);
|
||||
|
||||
if (!encrypt && this.CalcChecksum(fileContent, fileContent.Length) != 0)
|
||||
throw new FileLoadException("Checksum validation failed");
|
||||
|
||||
int chiffre = 0x0388;
|
||||
int step = 0;
|
||||
for (int i = 0; i < fileContent.Length - 4; i++)
|
||||
{
|
||||
byte b = fileContent[i];
|
||||
byte n = (byte) (b ^ (chiffre >> 8));
|
||||
fileContent[i] = n;
|
||||
if (++step < 256)
|
||||
chiffre += (encrypt ? n : b) + 0x96A3;
|
||||
else
|
||||
{
|
||||
chiffre = 0x0388;
|
||||
step = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (encrypt)
|
||||
this.UpdateChecksum(fileContent);
|
||||
|
||||
File.WriteAllBytes(output, fileContent);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RemoveHeader()
|
||||
private void RemoveHeader(string inputFile, string outputFile)
|
||||
{
|
||||
var data = File.ReadAllBytes(inputFile);
|
||||
if (this.CalcChecksum(data, data.Length) != 0)
|
||||
throw new FileLoadException("Checksum validation failed");
|
||||
|
||||
int offset;
|
||||
if (!this.ValidateFileSize(data, false, out offset)
|
||||
&& !this.ValidateFileSize(data, true, out offset))
|
||||
throw new FileLoadException("File size validation failed");
|
||||
|
||||
using (var stream = new FileStream(outputFile, FileMode.Create, FileAccess.Write))
|
||||
stream.Write(data, offset, data.Length - offset - 4);
|
||||
|
||||
this.fileHeader = new byte[offset];
|
||||
Array.Copy(data, 0, this.fileHeader, 0, offset);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ValidateFileSize()
|
||||
private bool ValidateFileSize(byte[] data, bool littleEndian, out int offset)
|
||||
{
|
||||
this.littleEndianByteOrder = littleEndian;
|
||||
offset = 30 + Tools.GetInt16(data, 28, littleEndian);
|
||||
if (offset >= data.Length) return false;
|
||||
this.dbSizeOffset = offset;
|
||||
int dbSize = Tools.GetInt32(data, offset, littleEndian);
|
||||
offset += 4;
|
||||
return data.Length == offset + dbSize + 4;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CalcChecksum()
|
||||
private uint CalcChecksum(byte[] data, int length)
|
||||
{
|
||||
uint v = 0xffffffff;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
byte b = data[i];
|
||||
v = (v << 8) ^ (uint)headerCypherTable[((v >> 24) ^ b) & 0xFF];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CleanTempFile()
|
||||
private void CleanTempFile(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.workFile != null)
|
||||
File.Delete(this.workFile);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region CreateDummySatellites()
|
||||
private void CreateDummySatellites()
|
||||
{
|
||||
for (int i = 1; i <= 4; i++)
|
||||
{
|
||||
var sat = new Satellite(i);
|
||||
sat.Name = "LNB "+i;
|
||||
sat.OrbitalPosition = i.ToString();
|
||||
this.DataRoot.Satellites.Add(i, sat);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region InitCharacterEncoding()
|
||||
private void InitCharacterEncoding(SQLiteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "PRAGMA encoding";
|
||||
this.charEncoding = cmd.ExecuteScalar() as string;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RepairCorruptedDatabaseImage()
|
||||
private void RepairCorruptedDatabaseImage(SQLiteCommand cmd)
|
||||
{
|
||||
cmd.CommandText = "REINDEX";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ReadChannels()
|
||||
private void ReadChannels(SQLiteCommand cmd)
|
||||
{
|
||||
string[] fieldNames = { "rowid", "major_channel", "physical_ch","sname", "freq", "skip", "running_status","free_CA_mode","child_lock",
|
||||
"profile1index","profile2index","profile3index","profile4index","stype", "onid", "tsid", "sid", "ntype", "ya_svcid", "delivery" };
|
||||
|
||||
const string sql = @"
|
||||
select s.rowid,s.major_channel,s.physical_ch,cast(s.sname as blob),t.freq,s.skip,s.running_status,s.free_CA_mode,s.child_lock,
|
||||
profile1index,profile2index,profile3index,profile4index,s.stype,s.onid,s.tsid,s.svcid,s.ntype,s.ya_svcid,delivery
|
||||
from SVL s
|
||||
left outer join TSL t on s.ntype=t.ntype and s.physical_ch=t.physical_ch and s.tsid=t.tsid
|
||||
order by s.ntype,major_channel
|
||||
";
|
||||
|
||||
var fields = this.GetFieldMap(fieldNames);
|
||||
|
||||
cmd.CommandText = sql;
|
||||
using (var r = cmd.ExecuteReader())
|
||||
{
|
||||
while (r.Read())
|
||||
{
|
||||
ChannelInfo channel = new DbChannel(r, fields, this.DataRoot, this.DefaultEncoding);
|
||||
if (!channel.IsDeleted)
|
||||
{
|
||||
var channelList = this.DataRoot.GetChannelList(channel.SignalSource);
|
||||
if (channelList != null)
|
||||
this.DataRoot.AddChannel(channelList, channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetFieldMap()
|
||||
private IDictionary<string, int> GetFieldMap(string[] fieldNames)
|
||||
{
|
||||
Dictionary<string, int> field = new Dictionary<string, int>();
|
||||
for (int i = 0; i < fieldNames.Length; i++)
|
||||
field[fieldNames[i]] = i;
|
||||
return field;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region DefaultEncoding
|
||||
public override Encoding DefaultEncoding
|
||||
{
|
||||
get { return base.DefaultEncoding; }
|
||||
set
|
||||
{
|
||||
base.DefaultEncoding = value;
|
||||
foreach (var list in this.DataRoot.ChannelLists)
|
||||
{
|
||||
foreach(var channel in list.Channels)
|
||||
channel.ChangeEncoding(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Save()
|
||||
public override void Save(string tvOutputFile)
|
||||
{
|
||||
this.FileName = tvOutputFile;
|
||||
|
||||
string channelConnString = "Data Source=" + this.workFile;
|
||||
using (var conn = new SQLiteConnection(channelConnString))
|
||||
{
|
||||
conn.Open();
|
||||
using (var cmd = conn.CreateCommand())
|
||||
{
|
||||
using (var trans = conn.BeginTransaction())
|
||||
{
|
||||
this.WriteChannels(cmd, this.avbtChannels);
|
||||
this.WriteChannels(cmd, this.avbcChannels);
|
||||
this.WriteChannels(cmd, this.dvbtChannels);
|
||||
this.WriteChannels(cmd, this.dvbcChannels);
|
||||
this.WriteChannels(cmd, this.dvbsChannels);
|
||||
this.WriteChannels(cmd, this.satipChannels);
|
||||
this.WriteChannels(cmd, this.freesatChannels);
|
||||
trans.Commit();
|
||||
}
|
||||
this.RepairCorruptedDatabaseImage(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
this.WriteCypheredFile();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteChannels()
|
||||
private void WriteChannels(SQLiteCommand cmd, ChannelList channelList)
|
||||
{
|
||||
cmd.CommandText = "update SVL set major_channel=@progNr, profile1index=@fav1, profile2index=@fav2, profile3index=@fav3, profile4index=@fav4, child_lock=@lock, skip=@skip where rowid=@rowid";
|
||||
cmd.Parameters.Clear();
|
||||
cmd.Parameters.Add(new SQLiteParameter("@rowid", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@progNr", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@fav1", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@fav2", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@fav3", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@fav4", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@lock", DbType.Int32));
|
||||
cmd.Parameters.Add(new SQLiteParameter("@skip", DbType.Int32));
|
||||
cmd.Prepare();
|
||||
foreach (ChannelInfo channelInfo in channelList.Channels)
|
||||
{
|
||||
var channel = channelInfo as DbChannel;
|
||||
if (channel == null) // skip reference list proxy channels
|
||||
continue;
|
||||
if (channel.NewProgramNr < 0 || channel.OldProgramNr < 0)
|
||||
continue;
|
||||
cmd.Parameters["@rowid"].Value = channel.RecordIndex;
|
||||
cmd.Parameters["@progNr"].Value = channel.NewProgramNr;
|
||||
for (int fav = 0; fav < 4; fav++)
|
||||
cmd.Parameters["@fav" + (fav + 1)].Value = Math.Max(0, channel.FavIndex[fav]);
|
||||
cmd.Parameters["@lock"].Value = channel.Lock;
|
||||
cmd.Parameters["@skip"].Value = channel.Skip;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// delete unassigned channels
|
||||
cmd.CommandText = "delete from SVL where rowid=@rowid";
|
||||
cmd.Parameters.Clear();
|
||||
cmd.Parameters.Add(new SQLiteParameter("@rowid", DbType.Int32));
|
||||
foreach (ChannelInfo channel in channelList.Channels)
|
||||
{
|
||||
if (channel.NewProgramNr == -1 && channel.OldProgramNr >= 0)
|
||||
{
|
||||
cmd.Parameters["@rowid"].Value = channel.RecordIndex;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteCypheredFile()
|
||||
private void WriteCypheredFile()
|
||||
{
|
||||
switch (this.cypherMode)
|
||||
{
|
||||
case CypherMode.None:
|
||||
break;
|
||||
case CypherMode.Encryption:
|
||||
this.CypherFile(this.workFile, this.FileName, true);
|
||||
break;
|
||||
case CypherMode.HeaderAndChecksum:
|
||||
this.WriteFileWithHeaderAndChecksum();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WriteFileWithHeaderAndChecksum()
|
||||
private void WriteFileWithHeaderAndChecksum()
|
||||
{
|
||||
long workFileSize = new FileInfo(this.workFile).Length;
|
||||
byte[] data = new byte[this.fileHeader.Length + workFileSize + 4];
|
||||
Array.Copy(fileHeader, data, fileHeader.Length);
|
||||
using (var stream = new FileStream(this.workFile, FileMode.Open, FileAccess.Read))
|
||||
stream.Read(data, fileHeader.Length, (int)workFileSize);
|
||||
|
||||
Tools.SetInt32(data, this.dbSizeOffset, (int)workFileSize, this.littleEndianByteOrder);
|
||||
this.UpdateChecksum(data);
|
||||
|
||||
using (var stream = new FileStream(this.FileName, FileMode.Create, FileAccess.Write))
|
||||
stream.Write(data, 0, data.Length);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UpdateChecksum()
|
||||
private void UpdateChecksum(byte[] data)
|
||||
{
|
||||
uint checksum = this.CalcChecksum(data, data.Length - 4);
|
||||
data[data.Length - 1] = (byte)(checksum & 0xFF);
|
||||
data[data.Length - 2] = (byte)((checksum >> 8) & 0xFF);
|
||||
data[data.Length - 3] = (byte)((checksum >> 16) & 0xFF);
|
||||
data[data.Length - 4] = (byte)((checksum >> 24) & 0xFF);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetFileInformation()
|
||||
public override string GetFileInformation()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append(base.GetFileInformation());
|
||||
|
||||
sb.Append("Content type: ");
|
||||
switch (this.GetCypherMode(this.FileName))
|
||||
{
|
||||
case CypherMode.None: sb.AppendLine("unencrypted SQLite database"); break;
|
||||
case CypherMode.Encryption: sb.AppendLine("encrypted SQLite database"); break;
|
||||
case CypherMode.HeaderAndChecksum:
|
||||
sb.AppendLine("embedded SQLite database");
|
||||
sb.Append("Byte order: ").AppendLine(this.littleEndianByteOrder ?
|
||||
"little-endian (least significant byte first)" : "big-endian (most significant byte first)");
|
||||
break;
|
||||
}
|
||||
sb.Append("Character encoding: ").AppendLine(this.charEncoding);
|
||||
return sb.ToString();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
15
source/ChanSort.Loader.Panasonic/SerializerPlugin.cs
Normal file
15
source/ChanSort.Loader.Panasonic/SerializerPlugin.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using ChanSort.Api;
|
||||
|
||||
namespace ChanSort.Loader.Panasonic
|
||||
{
|
||||
public class SerializerPlugin : ISerializerPlugin
|
||||
{
|
||||
public string PluginName { get { return "Panasonic *.db,*.bin"; } }
|
||||
public string FileFilter { get { return "*.db;*.bin"; } }
|
||||
|
||||
public SerializerBase CreateSerializer(string inputFile)
|
||||
{
|
||||
return new Serializer(inputFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user