- complete rework of TLL and SCM loaders, removing all "unsafe" code

- fixed various issues with SCM files
This commit is contained in:
hbeham
2013-04-03 12:47:24 +02:00
parent e194ff983b
commit 994235e020
78 changed files with 4896 additions and 2961 deletions

View File

@@ -0,0 +1,29 @@
using ChanSort.Api;
namespace ChanSort.Loader.ScmFile
{
internal class AnalogChannel : ScmChannelBase
{
private const string _Skip = "Skip";
private const string _Frequency = "offFrequency";
#region ctor()
public AnalogChannel(int slot, SignalSource signalSource, DataMapping mapping, decimal freq) : base(mapping)
{
this.InitCommonData(slot, signalSource, mapping);
this.FreqInMhz = (decimal)mapping.GetFloat(_Frequency); // C,D,E series have the value in the data record
if (this.FreqInMhz == 0) // for B series take it from the Tuning table
this.FreqInMhz = freq;
if (this.FreqInMhz == 0) // fallback since Freq is part of the UID and requires a unique value
this.FreqInMhz = slot;
this.Skip = mapping.GetFlag(_Skip);
this.ChannelOrTransponder = "";
}
#endregion
}
}

View File

@@ -1,72 +0,0 @@
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.ScmFile
{
internal class AnalogChannelDataMapping : ChannelMappingBase
{
const string offFrequency = "offFrequency";
const string offChecksum = "offChecksum";
#region ctor()
public AnalogChannelDataMapping(IniFile.Section settings, int length) :
base(settings, length, new UnicodeEncoding(true, false))
{
}
#endregion
#region Favorites
public override Favorites Favorites
{
get
{
if (this.DataLength < 64)
return base.Favorites;
byte fav = 0;
byte mask = 0x01;
foreach (int off in this.GetOffsets(offFavorites))
{
if (this.GetByte(off) == 1)
fav |= mask;
mask <<= 1;
}
return (Favorites)fav;
}
set
{
if (this.DataLength < 64)
{
base.Favorites = value;
return;
}
int intValue = (int)value;
foreach (int off in this.GetOffsets(offFavorites))
{
if ((intValue & 1) != 0)
this.SetByte(off, 1);
intValue >>= 1;
}
}
}
#endregion
#region Frequency
public float Frequency
{
get { return this.GetFloat(offFrequency); }
set { this.SetFloat(offFrequency, value); }
}
#endregion
#region Checksum
public byte Checksum
{
get { return this.GetByte(offChecksum); }
set { this.SetByte(offChecksum, value); }
}
#endregion
}
}

View File

@@ -8,8 +8,8 @@
<ProjectGuid>{A1C9A98D-368A-44E8-9B7F-7EACA46C9EC5}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ChanSort.Plugin.ScmFile</RootNamespace>
<AssemblyName>ChanSort.Plugin.ScmFile</AssemblyName>
<RootNamespace>ChanSort.Loader.ScmFile</RootNamespace>
<AssemblyName>ChanSort.Loader.ScmFile</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
@@ -37,7 +37,7 @@
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
@@ -67,14 +67,15 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AnalogChannelDataMapping.cs" />
<Compile Include="DvbSChannelDataMapping.cs" />
<Compile Include="DvbCtChannelDataMapping.cs" />
<Compile Include="AnalogChannel.cs" />
<Compile Include="DigitalChannel.cs" />
<Compile Include="ModelConstants.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SatChannel.cs" />
<Compile Include="SatelliteMapping.cs" />
<Compile Include="ScmChannelBase.cs" />
<Compile Include="ScmSerializer.cs" />
<Compile Include="ScmSerializerPlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ScmStructures.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ChanSort.Api\ChanSort.Api.csproj">
@@ -82,11 +83,6 @@
<Name>ChanSort.Api</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="ChanSort.Plugin.ScmFile.ini">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</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.

View File

@@ -1,334 +0,0 @@
[Series:B]
SatDataBase.dat = 145
TransponderDataBase.dat = 49
FineTune = 20
FineTune_Digital = 28
map-AirA = 28
map-AirD = 248
map-CableD = 248
map-SateD = 144
Favorites = 4
[Series:C]
SatDataBase.dat = 145
TransponderDataBase.dat = 45
map-AirA = 40
map-AirD = 292
map-CableD = 292
map-SateD = 144
Favorites = 4
[Series:D]
SatDataBase.dat = 145
TransponderDataBase.dat = 45
map-AirA = 64
map-AirD = 320
map-CableD = 320
map-SateD = 172
map-AstraHDPlusD = 212
Favorites = 5
[Series:E]
SatDataBase.dat = 145
TransponderDataBase.dat = 45
map-AirA = 64
map-AirD = 320
map-CableD = 320
map-SateD = 168
map-AstraHDPlusD = 212
Favorites = 5
[Analog:28]
; map-AirA and map-CableA for B series
offInUse = 0
maskInUse = 0x02
;offNameLength = 1
offProgramNr = 4
offFavorites =
offName = 12
lenName = 12
offChecksum = 27
[Analog:40]
; map-AirA and map-CableA for C series
offInUse = 1
maskInUse = 0x01
offSkip = 2
maskSkip = 0x01
offLock = 6
maskLock = 0x01
offTuned = 8
maskTuned = 0x01
offProgramNr = 9
offSlotNr = 16
offNameLength = 18
offName = 20
offFrequency = 32
offFavorites = 38
offChecksum = 39
[Analog:64]
; map-AirA and map-CableA for D series
offInUse = 1
maskInUse = 0x01
offSkip = 2
maskSkip = 0x01
offLock = 6
maskLock = 0x01
offTuned = 8
maskTuned = 0x01
offProgramNr = 9
offSlotNr = 16
offNameLength = 18
offName = 20
offFrequency = 32
offFavorite = 36,40,44,48,52
offChecksum = 63
[FineTune:20]
offIsCable = 0
maskIsCable = 0x01
offSlotNr = 4
offFrequency = 8
[FineTune_Digital:28]
offIsCable = 0
maskIsCable = 0x01
offChannelTransponder = 4
offFrequency = 16
[DvbCT:248]
; map-AirD and map-CableD for B series
offProgramNr = 0
offVideoPid = 2
offPcrPid = 4
offServiceId = 10
offStatus = 8
offQam = 7
offServiceType = 9
offEncrypted = 23
maskEncrypted = 0xff
offSymbolRate = 32
offLock = 244
maskLock = 0x01
offOriginalNetworkId = 12
offNetworkId = 14
offBouquet = 34
offChannelTransponder = 26
offLogicalProgramNr = 28
offTransportStreamId = 36
offName = 44
lenName = 100
offFavorites = 246
offChecksum = 247
offCodec =
offServiceProviderId =
offShortName =
lenShortName =
offVideoFormat =
[DvbCT:292]
; map-AirD and map-CableD for C series
offProgramNr = 0
offVideoPid = 2
offPcrPid = 4
offServiceId = 6
offStatus =
offQam = 12
offBandwidth = 14
offServiceType = 15
offCodec = 16
offHRes = 20
offVRes = 22
offEncrypted = 24
maskEncrypted = 0xff
offFrameRate = 25
offSymbolRate = 28
offLock = 31
maskLock = 0x01
offOriginalNetworkId = 32
offNetworkId = 34
offServiceProviderId = 40
offChannelTransponder = 42
offLogicalProgramNr = 44
offTransportStreamId = 48
offName = 64
lenName = 200
offShortName = 264
lenShortName = 18
offVideoFormat = 282
offFavorites = 289
offChecksum = 291
offBouquet =
[DvbCT:320]
; map-AirD and map-CableD for D and E series
offProgramNr = 0
offVideoPid = 2
offPcrPid = 4
offServiceId = 6
offStatus =
offQam = 12
offBandwidth = 14
offServiceType = 15
offCodec = 16
offHRes = 20
offVRes = 22
offEncrypted = 24
maskEncrypted = 0xff
offFrameRate = 25
offSymbolRate = 28
offLock = 31
maskLock = 0x01
offOriginalNetworkId = 32
offNetworkId = 34
offServiceProviderId = 40
offChannelTransponder = 42
offLogicalProgramNr = 44
offTransportStreamId = 48
offName = 64
lenName = 200
offShortName = 264
lenShortName = 18
offVideoFormat = 282
offFavorites = 292,296,300,304,308
offChecksum = 319
offBouquet =
[DvbS:144]
; map-SateD for B and C Series
offProgramNr = 0
offVideoPid = 2
offPcrPid = 4
offInUse = 7
maskInUse = 0x01
offLock = 13
maskLock = 0x01
offServiceType = 14
offServiceId = 16
offTransponderNr = 18
offSatelliteNr = 20
offTransportStreamId = 24
offOriginalNetworkId = 28
offHRes = 32
offVRes = 34
offName = 36
lenName = 100
offEncrypted = 136
maskEncrypted = 0x01
offBouquet = 138
offFavorites = 142
offChecksum = 143
offCodec =
offSymbolRate =
offNetworkId =
offServiceProviderId =
offChannelTransponder =
offLogicalProgramNr =
offShortName =
lenShortName =
offVideoFormat =
[DvbS:172]
; map-SateD for D Series
offProgramNr = 0
offVideoPid = 2
offPcrPid = 4
offInUse = 7
maskInUse = 0x01
offLock = 13
maskLock = 0x01
offServiceType = 14
offServiceId = 16
offTransponderNr = 18
offSatelliteNr = 20
offTransportStreamId = 24
offOriginalNetworkId = 28
offHRes = 32
offVRes = 34
offName = 36
lenName = 100
offEncrypted = 136
maskEncrypted = 0x01
offBouquet = 138
offFavorites = 140,144,148,152,156
offChecksum = 171
offCodec =
offSymbolRate =
offNetworkId =
offServiceProviderId =
offChannelTransponder =
offLogicalProgramNr =
offShortName =
lenShortName =
offVideoFormat =
[DvbS:168]
; map-SateD for E Series
offProgramNr = 0
offVideoPid = 2
offPcrPid = 4
offInUse = 7
maskInUse = 0x01
offLock = 13
maskLock = 0x01
offServiceType = 14
offServiceId = 16
offTransponderNr = 18
offSatelliteNr = 20
offTransportStreamId = 24
offOriginalNetworkId = 28
offHRes = 32
offVRes = 34
offName = 36
offEncrypted = 136
maskEncrypted = 0x01
lenName = 100
offBouquet = 138
offFavorites = 140,144,148,152,156
offChecksum = 167
offCodec =
offSymbolRate =
offNetworkId =
offServiceProviderId =
offChannelTransponder =
offLogicalProgramNr =
offShortName =
lenShortName =
offVideoFormat =
[AstraHDPlusD:212]
; map-AstraHDPlusD for D and E Series
offProgramNr = 0,20
offVideoPid =
offPcrPid =
offInUse = 14
maskInUse = 0xff
offLock =
maskLock = 0x01
offServiceType = 14
offServiceId = 16
offTransponderNr = 18
offSatelliteNr =
offTransportStreamId = 36
offOriginalNetworkId = 32
offHRes =
offVRes =
offName = 48
offEncrypted = 180
maskEncrypted = 0x01
lenName = 100
offBouquet = 138
offFavorites = 184,188,192,196,200
offChecksum = 211
offCodec =
offSymbolRate =
offNetworkId =
offServiceProviderId =
offChannelTransponder =
offLogicalProgramNr =
offShortName =
lenShortName =
offVideoFormat =

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
using ChanSort.Api;
namespace ChanSort.Loader.ScmFile
{
public class DigitalChannel : ScmChannelBase
{
private const string _ChannelOrTransponder = "offChannelTransponder";
public DigitalChannel(int slot, SignalSource signalSource, DataMapping data, IDictionary<int, decimal> transpFreq) : base(data)
{
this.InitCommonData(slot, signalSource, data);
this.InitDvbData(data);
int transp = data.GetByte(_ChannelOrTransponder);
decimal freq = transpFreq.TryGet(transp);
if (freq == 0)
freq = transp*8 + 106;
this.ChannelOrTransponder = ((int)(freq-106)/8).ToString();
this.FreqInMhz = freq;
}
}
}

View File

@@ -1,63 +0,0 @@
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.ScmFile
{
internal class DvbCtChannelDataMapping : DvbChannelMappingBase
{
const string offChecksum = "offChecksum";
#region ctor()
public DvbCtChannelDataMapping(IniFile.Section settings, int dataLength)
: base(settings, dataLength, new UnicodeEncoding(true, false))
{
}
#endregion
#region Checksum
public byte Checksum
{
get { return this.GetByte(offChecksum); }
set { this.SetByte(offChecksum, value); }
}
#endregion
#region Favorites
public override Favorites Favorites
{
get
{
if (this.DataLength < 320)
return base.Favorites;
byte fav = 0;
byte mask = 0x01;
foreach (int off in this.GetOffsets(offFavorites))
{
if (this.GetByte(off) == 1)
fav |= mask;
mask <<= 1;
}
return (Favorites)fav;
}
set
{
if (this.DataLength < 320)
{
base.Favorites = value;
return;
}
int intValue = (int)value;
foreach (int off in this.GetOffsets(offFavorites))
{
if ((intValue & 1) != 0)
this.SetByte(off, 1);
intValue >>= 1;
}
}
}
#endregion
}
}

View File

@@ -1,83 +0,0 @@
using System.Text;
using ChanSort.Api;
namespace ChanSort.Plugin.ScmFile
{
internal class DvbSChannelDataMapping : DvbChannelMappingBase
{
private const string offChecksum = "offChecksum";
private const string offTransponderNr = "offTransponderNr";
private const string offSatelliteNr = "offSatelliteNr";
private readonly bool hasExtendedFavorites;
#region ctor()
public DvbSChannelDataMapping(IniFile.Section settings, int dataLength)
: base(settings, dataLength, new UnicodeEncoding(true, false))
{
this.hasExtendedFavorites = dataLength >= 168;
}
#endregion
#region TransponderNr
public ushort TransponderNr
{
get { return this.GetWord(offTransponderNr); }
set { this.SetWord(offTransponderNr, value); }
}
#endregion
#region SatelliteNr
public ushort SatelliteNr
{
get { return this.GetWord(offSatelliteNr); }
set { this.SetWord(offSatelliteNr, value); }
}
#endregion
#region Favorites
public override Favorites Favorites
{
get
{
if (!this.hasExtendedFavorites)
return base.Favorites;
byte fav = 0;
byte mask = 0x01;
foreach (int off in this.GetOffsets(offFavorites))
{
if (this.GetDword(off) == 1)
fav |= mask;
mask <<= 1;
}
return (Favorites)fav;
}
set
{
if (!this.hasExtendedFavorites)
{
base.Favorites = value;
return;
}
int intValue = (int)value;
foreach (int off in this.GetOffsets(offFavorites))
{
if ((intValue & 1) != 0)
this.SetDword(off, 1);
intValue >>= 1;
}
}
}
#endregion
#region Checksum
public byte Checksum
{
get { return this.GetByte(offChecksum); }
set { this.SetByte(offChecksum, value); }
}
#endregion
}
}

View File

@@ -1,6 +1,6 @@
using ChanSort.Api;
namespace ChanSort.Plugin.ScmFile
namespace ChanSort.Loader.ScmFile
{
internal class ModelConstants
{
@@ -13,12 +13,14 @@ namespace ChanSort.Plugin.ScmFile
public readonly int avbtFineTuneLength;
public readonly int dvbtFineTuneLength;
public readonly Favorites supportedFavorites;
public readonly int ptcLength;
public ModelConstants(IniFile.Section iniSection)
{
this.avbtChannelLength = iniSection.GetInt("map-AirA");
this.dvbtChannelLength = iniSection.GetInt("map-AirD");
this.dvbsChannelLength = iniSection.GetInt("map-SateD");
this.ptcLength = iniSection.GetInt("PTC");
this.hdplusChannelLength = iniSection.GetInt("map-AstraHDPlusD");
this.dvbsSatelliteLength = iniSection.GetInt("SatDataBase.dat");
this.dvbsTransponderLength = iniSection.GetInt("TransponderDataBase.dat");

View File

@@ -5,11 +5,11 @@ 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.Plugin.ScmFile")]
[assembly: AssemblyTitle("ChanSort.Loader.ScmFile")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ChanSort.Plugin.ScmFile")]
[assembly: AssemblyProduct("ChanSort.Loader.ScmFile")]
[assembly: AssemblyCopyright("Copyright © 2012")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -0,0 +1,34 @@
using ChanSort.Api;
namespace ChanSort.Loader.ScmFile
{
class SatChannel : ScmChannelBase
{
private const string _TransponderIndex = "offTransponderIndex";
public SatChannel(int slot, DataMapping data, DataRoot dataRoot) : base(data)
{
this.InitCommonData(slot, SignalSource.DvbS, data);
if (!this.InUse)
return;
this.InitDvbData(data);
int transponderIndex = data.GetWord(_TransponderIndex);
Transponder transponder = dataRoot.Transponder.TryGet(transponderIndex);
if (transponder == null)
{
dataRoot.Warnings.AppendLine("Invalid transponder index: " + transponderIndex);
return;
}
Satellite sat = transponder.Satellite;
this.Satellite = sat.Name;
this.SatPosition = sat.OrbitalPosition;
this.Polarity = transponder.Polarity;
this.SymbolRate = transponder.SymbolRate;
this.FreqInMhz = transponder.FrequencyInMhz;
this.ChannelOrTransponder = "";
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
using System.Text;
namespace ChanSort.Loader.ScmFile
{
internal class SatelliteMapping
{
private static readonly Encoding utf16Encoding = new UnicodeEncoding(false, false);
private readonly byte[] data;
public int BaseOffset;
public SatelliteMapping(byte[] data, int offset)
{
this.data = data;
this.BaseOffset = offset;
}
public byte MagicMarker { get { return data[BaseOffset]; } }
public int SatelliteNr { get { return BitConverter.ToInt32(data, BaseOffset + 1); } }
public string Name { get { return utf16Encoding.GetString(data, BaseOffset + 9, 128); } }
public bool IsEast { get { return BitConverter.ToInt32(data, BaseOffset + 137) != 0; } }
public decimal Longitude { get { return (decimal)BitConverter.ToInt32(data, BaseOffset + 141) / 10; } }
}
}

View File

@@ -0,0 +1,156 @@
using System.Text;
using ChanSort.Api;
namespace ChanSort.Loader.ScmFile
{
public class ScmChannelBase : ChannelInfo
{
// common
private const string _InUse = "InUse";
private const string _ProgramNr = "offProgramNr";
private const string _Name = "offName";
private const string _NameLength = "offNameLength";
private const string _ShortName = "offShortName";
private const string _Favorites = "offFavorites";
private const string _Deleted = "Deleted";
private const string _Encrypted = "Encrypted";
private const string _Lock = "Lock";
private const string _Checksum = "offChecksum";
// DVB
private const string _ServiceId = "offServiceId";
private const string _VideoPid = "offVideoPid";
private const string _AudioPid = "offAudioPid";
private const string _OriginalNetworkId = "offOriginalNetworkId";
private const string _TransportStreamId = "offTransportStreamId";
private const string _ServiceType = "offServiceType";
private const string _SymbolRate = "offSymbolRate";
private static readonly Encoding Utf16BigEndian = new UnicodeEncoding(true, false);
protected readonly DataMapping mapping;
protected readonly byte[] rawData;
internal readonly int baseOffset;
internal bool InUse { get; set; }
protected ScmChannelBase(DataMapping data)
{
this.mapping = data;
this.rawData = data.Data;
this.baseOffset = data.BaseOffset;
this.mapping.DefaultEncoding = Utf16BigEndian;
}
#region InitCommonData()
protected void InitCommonData(int slot, SignalSource signalSource, DataMapping data)
{
this.InUse = data.GetFlag(_InUse);
this.RecordIndex = slot;
this.RecordOrder = slot;
this.SignalSource = signalSource;
this.SignalType = SignalType.Mixed;
this.OldProgramNr = data.GetWord(_ProgramNr);
this.Name = data.GetString(_Name, data.Settings.GetInt("lenName"));
this.Favorites = this.ParseRawFavorites();
this.Lock = data.GetFlag(_Lock);
this.Encrypted = data.GetFlag(_Encrypted);
this.IsDeleted = data.GetFlag(_Deleted);
}
#endregion
#region ParseRawFavorites()
private Favorites ParseRawFavorites()
{
var offsets = mapping.GetOffsets(_Favorites);
if (offsets.Length == 1) // series B,C
return (Favorites) mapping.GetByte(_Favorites);
// series D,E
byte fav = 0;
byte mask = 0x01;
foreach (int off in offsets)
{
if ((System.BitConverter.ToInt32(this.rawData, baseOffset + off) + 1) > 1) // -1 and 0 mean "not set"
fav |= mask;
mask <<= 1;
}
return (Favorites) fav;
}
#endregion
#region InitDvbData()
protected void InitDvbData(DataMapping data)
{
this.ShortName = data.GetString(_ShortName, data.Settings.GetInt("lenShortName"));
this.ServiceId = data.GetWord(_ServiceId);
//this.PcrPid = data.GetWord(_PcrPid);
this.VideoPid = data.GetWord(_VideoPid);
this.AudioPid = data.GetWord(_AudioPid);
this.OriginalNetworkId = data.GetWord(_OriginalNetworkId);
this.TransportStreamId = data.GetWord(_TransportStreamId);
this.ServiceType = data.GetByte(_ServiceType);
this.SymbolRate = data.GetWord(_SymbolRate);
}
#endregion
#region GetSignalType()
protected SignalType GetSignalType(uint programNr)
{
if ((programNr & 0x4000) != 0)
return SignalType.Radio;
return SignalType.Tv;
}
#endregion
#region UpdateRawData()
public override void UpdateRawData()
{
mapping.SetDataPtr(this.rawData, this.baseOffset);
mapping.SetWord(_ProgramNr, this.NewProgramNr);
if (this.IsNameModified)
{
mapping.SetString(_Name, this.Name, mapping.Settings.GetInt("lenName"));
mapping.SetByte(_NameLength, this.Name.Length);
this.IsNameModified = false;
}
this.UpdateRawFavorites();
mapping.SetFlag(_Lock, this.Lock);
if (this.NewProgramNr == 0)
mapping.SetFlag(_Deleted, true);
this.UpdateChecksum();
}
#endregion
#region UpdateRawFavorites()
private void UpdateRawFavorites()
{
var offsets = mapping.GetOffsets(_Favorites);
if (offsets.Length == 1) // series B,C
mapping.SetByte(_Favorites, (byte)this.Favorites & 0x0F);
// series D,E
byte fav = (byte)this.Favorites;
byte mask = 0x01;
foreach (int off in offsets)
{
this.rawData[baseOffset + off] = (byte)((fav & mask) == 0 ? 0 : 1);
mask <<= 1;
}
}
#endregion
#region UpdateChecksum()
private void UpdateChecksum()
{
var offChecksum = this.mapping.GetOffsets(_Checksum)[0];
byte crc = 0;
for (int i = this.baseOffset; i < offChecksum; i++)
crc += this.rawData[i];
this.rawData[offChecksum] = crc;
}
#endregion
}
}

View File

@@ -1,23 +1,35 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using ChanSort.Api;
using ICSharpCode.SharpZipLib.Zip;
namespace ChanSort.Plugin.ScmFile
namespace ChanSort.Loader.ScmFile
{
class ScmSerializer : SerializerBase
{
public struct ChannelAndFreq
{
public int Channel;
public decimal Frequency;
public ChannelAndFreq(int ch, decimal freq)
{
this.Channel = ch;
this.Frequency = freq;
}
}
private readonly Dictionary<string, ModelConstants> modelConstants = new Dictionary<string, ModelConstants>();
private readonly MappingPool<AnalogChannelDataMapping> analogMappings = new MappingPool<AnalogChannelDataMapping>("Analog");
private readonly MappingPool<DvbCtChannelDataMapping> dvbctMappings = new MappingPool<DvbCtChannelDataMapping>("DVB-C/T");
private readonly MappingPool<DvbSChannelDataMapping> dvbsMappings = new MappingPool<DvbSChannelDataMapping>("DVB-S");
private readonly MappingPool<DvbSChannelDataMapping> hdplusMappings = new MappingPool<DvbSChannelDataMapping>("AstraHDPlus");
private readonly MappingPool<DataMapping> analogMappings = new MappingPool<DataMapping>("Analog");
private readonly MappingPool<DataMapping> dvbctMappings = new MappingPool<DataMapping>("DVB-C/T");
private readonly MappingPool<DataMapping> dvbsMappings = new MappingPool<DataMapping>("DVB-S");
private readonly MappingPool<DataMapping> hdplusMappings = new MappingPool<DataMapping>("AstraHDPlus");
private readonly MappingPool<DataMapping> analogFineTuneMappings = new MappingPool<DataMapping>("FineTune");
private readonly MappingPool<DataMapping> ptccableMappings = new MappingPool<DataMapping>("PTC");
private readonly MappingPool<DataMapping> transponderMappings = new MappingPool<DataMapping>("TransponderDataBase");
private readonly ChannelList avbtChannels = new ChannelList(SignalSource.AnalogT, SignalType.Mixed);
private readonly ChannelList avbcChannels = new ChannelList(SignalSource.AnalogC, SignalType.Mixed);
private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC, SignalType.Mixed);
@@ -26,13 +38,14 @@ namespace ChanSort.Plugin.ScmFile
private readonly ChannelList hdplusChannels = new ChannelList(SignalSource.HdPlusD, SignalType.Mixed);
private readonly Dictionary<int, decimal> avbtFrequency = new Dictionary<int, decimal>();
private readonly Dictionary<int, decimal> avbcFrequency = new Dictionary<int, decimal>();
private readonly Dictionary<int, decimal> dvbcFrequency = new Dictionary<int, decimal>();
private readonly Dictionary<int, decimal> dvbtFrequency = new Dictionary<int, decimal>();
private byte[] avbtFileContent;
private byte[] avbcFileContent;
private byte[] dvbtFileContent;
private byte[] dvbcFileContent;
private byte[] dvbsFileContent;
private byte[] hdplusFileContent;
private UnsortedChannelMode unsortedChannelMode;
private ModelConstants c;
#region ctor()
@@ -61,15 +74,19 @@ namespace ChanSort.Plugin.ScmFile
if (section.Name.StartsWith("Series:"))
modelConstants.Add(section.Name, new ModelConstants(section));
else if (section.Name.StartsWith("Analog:"))
analogMappings.AddMapping(new AnalogChannelDataMapping(section, len));
analogMappings.AddMapping(len, new DataMapping(section));
else if (section.Name.StartsWith("DvbCT:"))
dvbctMappings.AddMapping(new DvbCtChannelDataMapping(section, len));
dvbctMappings.AddMapping(len, new DataMapping(section));
else if (section.Name.StartsWith("DvbS:"))
dvbsMappings.AddMapping(new DvbSChannelDataMapping(section, len));
dvbsMappings.AddMapping(len, new DataMapping(section));
else if (section.Name.StartsWith("FineTune:"))
analogFineTuneMappings.AddMapping(new DataMapping(section, len, null));
analogFineTuneMappings.AddMapping(len, new DataMapping(section));
else if (section.Name.StartsWith("AstraHDPlusD:"))
hdplusMappings.AddMapping(new DvbSChannelDataMapping(section, len));
hdplusMappings.AddMapping(len, new DataMapping(section));
else if (section.Name.StartsWith("TransponderDataBase.dat:"))
transponderMappings.AddMapping(len, new DataMapping(section));
else if (section.Name.StartsWith("PTC:"))
ptccableMappings.AddMapping(len, new DataMapping(section));
}
}
#endregion
@@ -85,8 +102,10 @@ namespace ChanSort.Plugin.ScmFile
ReadAnalogFineTuning(zip);
ReadAnalogChannels(zip, "map-AirA", this.avbtChannels, out this.avbtFileContent, this.avbtFrequency);
ReadAnalogChannels(zip, "map-CableA", this.avbcChannels, out this.avbcFileContent, this.avbcFrequency);
ReadDvbctChannels(zip, "map-AirD", this.dvbtChannels, out this.dvbtFileContent);
ReadDvbctChannels(zip, "map-CableD", this.dvbcChannels, out this.dvbcFileContent);
ReadDvbTransponderFrequenciesFromPtc(zip, "PTCAIR", this.dvbtFrequency);
ReadDvbctChannels(zip, "map-AirD", this.dvbtChannels, out this.dvbtFileContent, this.dvbtFrequency);
ReadDvbTransponderFrequenciesFromPtc(zip, "PTCCABLE", this.dvbcFrequency);
ReadDvbctChannels(zip, "map-CableD", this.dvbcChannels, out this.dvbcFileContent, this.dvbcFrequency);
ReadSatellites(zip);
ReadTransponder(zip, "TransponderDataBase.dat");
ReadTransponder(zip, "UserTransponderDataBase.dat");
@@ -250,7 +269,7 @@ namespace ChanSort.Plugin.ScmFile
#region ReadAnalogFineTuning()
private unsafe void ReadAnalogFineTuning(ZipFile zip)
private void ReadAnalogFineTuning(ZipFile zip)
{
int entrySize = c.avbtFineTuneLength;
if (entrySize == 0)
@@ -261,25 +280,22 @@ namespace ChanSort.Plugin.ScmFile
return;
var mapping = analogFineTuneMappings.GetMapping(c.avbtFineTuneLength);
fixed (byte* ptr = data)
mapping.SetDataPtr(data, 0);
int count = data.Length / c.avbtFineTuneLength;
for (int i = 0; i < count; i++)
{
mapping.DataPtr = ptr;
int count = data.Length / mapping.DataLength;
for (int i = 0; i < count; i++)
{
bool isCable = mapping.GetFlag("offIsCable", "maskIsCable"); // HACK: this is just a guess
int slot = mapping.GetWord("offSlotNr");
float freq = mapping.GetFloat("offFrequency");
var dict = isCable ? avbcFrequency : avbtFrequency;
dict[slot] = (decimal)freq;
mapping.Next();
}
bool isCable = mapping.GetFlag("offIsCable", "maskIsCable"); // HACK: this is just a guess
int slot = mapping.GetWord("offSlotNr");
float freq = mapping.GetFloat("offFrequency");
var dict = isCable ? avbcFrequency : avbtFrequency;
dict[slot] = (decimal)freq;
mapping.BaseOffset += c.avbtFineTuneLength;
}
}
#endregion
#region ReadAnalogChannels()
private unsafe void ReadAnalogChannels(ZipFile zip, string fileName, ChannelList list, out byte[] data, Dictionary<int,decimal> freq)
private void ReadAnalogChannels(ZipFile zip, string fileName, ChannelList list, out byte[] data, Dictionary<int,decimal> freq)
{
data = null;
int entrySize = c.avbtChannelLength;
@@ -291,48 +307,52 @@ namespace ChanSort.Plugin.ScmFile
return;
this.DataRoot.AddChannelList(list);
fixed (byte* ptr = data)
{
var rawChannel = analogMappings.GetMapping(entrySize);
rawChannel.DataPtr = ptr;
int count = data.Length / entrySize;
var rawChannel = analogMappings.GetMapping(entrySize);
rawChannel.SetDataPtr(data, 0);
int count = data.Length / entrySize;
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
MapAnalogChannel(rawChannel, slotIndex, list, freq);
rawChannel.DataPtr += entrySize;
}
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
MapAnalogChannel(rawChannel, slotIndex, list, freq.TryGet(slotIndex));
rawChannel.BaseOffset += entrySize;
}
}
#endregion
#region MapAnalogChannel()
private unsafe void MapAnalogChannel(AnalogChannelDataMapping rawChannel, int slotIndex, ChannelList list, Dictionary<int,decimal> freq)
private void MapAnalogChannel(DataMapping rawChannel, int slotIndex, ChannelList list, decimal freq)
{
if (!rawChannel.InUse)
AnalogChannel ci = new AnalogChannel(slotIndex, list.SignalSource, rawChannel, freq);
if (!ci.InUse)
return;
if (rawChannel.Checksum != CalcChecksum(rawChannel.DataPtr, c.avbtChannelLength))
this.DataRoot.Warnings.AppendFormat("{0}: Incorrect checksum for channel index {1}\r\n", list, slotIndex);
ChannelInfo ci = new ChannelInfo(list.SignalSource, list.SignalType, slotIndex, rawChannel.ProgramNr, rawChannel.Name);
ci.FreqInMhz = (decimal)Math.Round(rawChannel.Frequency, 2);
if (ci.FreqInMhz == 0)
ci.FreqInMhz = freq.TryGet(ci.RecordIndex);
if (ci.FreqInMhz == 0)
ci.FreqInMhz = slotIndex;
ci.Lock = rawChannel.Lock;
ci.Skip = rawChannel.Skip;
ci.Favorites = rawChannel.Favorites;
this.DataRoot.AddChannel(list, ci);
}
#endregion
#region ReadDvbTransponderFrequenciesFromPtc()
private void ReadDvbTransponderFrequenciesFromPtc(ZipFile zip, string file, IDictionary<int, decimal> table)
{
byte[] data = ReadFileContent(zip, file);
if (data == null)
return;
var mapping = ptccableMappings.GetMapping(c.ptcLength);
mapping.SetDataPtr(data, 0);
int count = data.Length / c.ptcLength;
for (int i = 0; i < count; i++)
{
int transp = mapping.GetWord("offChannelTransponder");
float freq = mapping.GetFloat("offFrequency");
table[transp] = (decimal)freq;
mapping.BaseOffset += c.ptcLength;
}
}
#endregion
#region ReadDvbctChannels()
private unsafe void ReadDvbctChannels(ZipFile zip, string fileName, ChannelList list, out byte[] data)
private void ReadDvbctChannels(ZipFile zip, string fileName, ChannelList list, out byte[] data, Dictionary<int, decimal> frequency)
{
data = null;
int entrySize = c.dvbtChannelLength;
@@ -344,204 +364,123 @@ namespace ChanSort.Plugin.ScmFile
return;
this.DataRoot.AddChannelList(list);
fixed (byte* ptr = data)
DataMapping rawChannel = dvbctMappings.GetMapping(entrySize);
rawChannel.SetDataPtr(data, 0);
int count = data.Length / entrySize;
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
DvbCtChannelDataMapping rawChannel = dvbctMappings.GetMapping(entrySize);
rawChannel.DataPtr = ptr;
int count = data.Length / entrySize;
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
MapDvbctChannel(rawChannel, slotIndex, list);
rawChannel.Next();
}
DigitalChannel ci = new DigitalChannel(slotIndex, list.SignalSource, rawChannel, frequency);
if (ci.OldProgramNr != 0)
this.DataRoot.AddChannel(list, ci);
rawChannel.BaseOffset += entrySize;
}
}
#endregion
#region MapDvbctChannel()
private unsafe void MapDvbctChannel(DvbCtChannelDataMapping rawChannel, int slotIndex, ChannelList list)
{
if (rawChannel.ProgramNr == 0)
return;
if (rawChannel.Checksum != CalcChecksum(rawChannel.DataPtr, rawChannel.DataLength))
this.DataRoot.Warnings.AppendFormat("{0}: Incorrect checksum for channel index {1}\r\n", list, slotIndex);
ChannelInfo ci = new ChannelInfo(list.SignalSource, list.SignalType, slotIndex, rawChannel.ProgramNr, rawChannel.Name);
ci.VideoPid = rawChannel.VideoPid;
ci.ServiceId = rawChannel.ServiceId;
ci.ServiceType = rawChannel.ServiceType;
ci.TransportStreamId = rawChannel.TransportStreamId;
ci.FreqInMhz = LookupData.Instance.GetDvbtTransponderFrequency(rawChannel.ChannelOrTransponder);
ci.OriginalNetworkId = rawChannel.OriginalNetworkId;
ci.Favorites = rawChannel.Favorites;
ci.Lock = rawChannel.Lock;
ci.ShortName = rawChannel.ShortName;
ci.SymbolRate = rawChannel.SymbolRate;
ci.Encrypted = rawChannel.Encrypted;
ci.ChannelOrTransponder = rawChannel.ChannelOrTransponder.ToString();
this.DataRoot.AddChannel(list, ci);
}
#endregion
#region ReadSatellites()
private unsafe void ReadSatellites(ZipFile zip)
private void ReadSatellites(ZipFile zip)
{
byte[] data = ReadFileContent(zip, "SatDataBase.dat");
if (data == null)
return;
var utf16Encoding = new UnicodeEncoding(false, false);
fixed (byte* ptr = data)
SatelliteMapping satMapping = new SatelliteMapping(data, 4);
int count = data.Length/this.c.dvbsSatelliteLength;
for (int i = 0; i < count; i++)
{
int count = data.Length/this.c.dvbsSatelliteLength;
for (int i = 0; i < count; i++)
{
SatDataBase* sat = (SatDataBase*)(ptr + 4 + i * this.c.dvbsSatelliteLength);
if (sat->Magic0x55 != 0x55)
throw new IOException("Unknown SatDataBase.dat format");
string name = utf16Encoding.GetString((byte*)sat->Name, 64*2);
string location = string.Format("{0}.{1}{2}", sat->LongitudeTimes10/10, sat->LongitudeTimes10%10, sat->IsWest != 0 ? "W" : "E");
if (satMapping.MagicMarker != 0x55)
throw new IOException("Unknown SatDataBase.dat format");
string location = string.Format("{0}{1}", satMapping.Longitude, satMapping.IsEast ? "E" : "W");
Satellite satellite = new Satellite(sat->SatelliteNr);
satellite.Name = name;
satellite.OrbitalPosition = location;
this.DataRoot.Satellites.Add(sat->SatelliteNr, satellite);
}
Satellite satellite = new Satellite(satMapping.SatelliteNr);
satellite.Name = satMapping.Name;
satellite.OrbitalPosition = location;
this.DataRoot.Satellites.Add(satMapping.SatelliteNr, satellite);
satMapping.BaseOffset += this.c.dvbsSatelliteLength;
}
}
#endregion
#region ReadTransponder()
private unsafe void ReadTransponder(ZipFile zip, string fileName)
private void ReadTransponder(ZipFile zip, string fileName)
{
byte[] data = ReadFileContent(zip, fileName);
if (data == null)
return;
fixed (byte* ptr = data)
int count = (data.Length-4)/c.dvbsTransponderLength;
var mapping = this.transponderMappings.GetMapping(c.dvbsTransponderLength);
for (int i=0; i<count; i++)
{
int count = data.Length/c.dvbsTransponderLength;
for (int i=0; i<count; i++)
mapping.SetDataPtr(data, 4 + i * c.dvbsTransponderLength);
if (mapping.GetByte("offMagicByte") == 0)
continue;
int transponderNr = (int)mapping.GetDword("offTransponderIndex");
if (transponderNr == 0)
continue;
int satelliteNr = (int)mapping.GetDword("offSatelliteIndex");
var sat = this.DataRoot.Satellites.TryGet(satelliteNr);
if (sat == null)
{
int baseOffset = 4 + i*c.dvbsTransponderLength;
TransponderDataBase* trans = (TransponderDataBase*) (ptr + baseOffset);
if (trans->Magic0x55 == 0)
continue;
if (trans->TransponderNr == 0)
continue;
var sat = this.DataRoot.Satellites.TryGet(trans->SatelliteNr);
if (sat == null)
{
DataRoot.Warnings.Append(string.Format("Transponder #{0} references invalid satellite #{1}",
trans->TransponderNr, trans->SatelliteNr));
continue;
}
Transponder transponder = new Transponder(trans->TransponderNr);
transponder.FrequencyInMhz = (uint) (trans->Frequency/1000);
transponder.Polarity = trans->IsVerticalPolarity == 1 ? 'V' : 'H';
transponder.SymbolRate = trans->SymbolRate/1000;
this.DataRoot.AddTransponder(sat, transponder);
DataRoot.Warnings.Append(string.Format("Transponder #{0} references invalid satellite #{1}",
transponderNr, satelliteNr));
continue;
}
Transponder transponder = new Transponder(transponderNr);
transponder.FrequencyInMhz = (uint)(mapping.GetDword("offFrequency")/1000);
transponder.SymbolRate = (int) (mapping.GetDword("offSymbolRate")/1000);
this.DataRoot.AddTransponder(sat, transponder);
}
}
#endregion
#region ReadDvbsChannels()
private unsafe void ReadDvbsChannels(ZipFile zip)
private void ReadDvbsChannels(ZipFile zip)
{
this.dvbsFileContent = ReadFileContent(zip, "map-SateD");
if (this.dvbsFileContent == null)
return;
this.DataRoot.AddChannelList(this.dvbsChannels);
fixed (byte* ptr = this.dvbsFileContent)
int entrySize = c.dvbsChannelLength;
int count = this.dvbsFileContent.Length/entrySize;
DataMapping mapping = dvbsMappings.GetMapping(entrySize);
mapping.SetDataPtr(dvbsFileContent, 0);
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
int entrySize = c.dvbsChannelLength;
int count = this.dvbsFileContent.Length/entrySize;
DvbSChannelDataMapping mapping = dvbsMappings.GetMapping(entrySize);
mapping.DataPtr = ptr;
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
MapDvbsChannel(this.dvbsChannels, mapping, slotIndex);
mapping.Next();
}
SatChannel ci = new SatChannel(slotIndex, mapping, this.DataRoot);
if (ci.InUse)
this.DataRoot.AddChannel(this.dvbsChannels, ci);
mapping.BaseOffset += entrySize;
}
}
#endregion
#region MapDvbsChannel()
private void MapDvbsChannel(ChannelList channelList, DvbSChannelDataMapping rawChannel, int slotIndex)
{
if (!rawChannel.InUse)
return;
Transponder transponder = this.DataRoot.Transponder.TryGet(rawChannel.TransponderNr);
Satellite satellite = transponder == null ? null : transponder.Satellite;
string satPosition = satellite != null ? satellite.OrbitalPosition : "#" + rawChannel.SatelliteNr;
string satName = satellite != null ? satellite.Name : null;
ChannelInfo ci = new ChannelInfo(channelList.SignalSource, SignalType.Mixed, slotIndex, rawChannel.ProgramNr, rawChannel.Name);
ci.Satellite = satName;
ci.SatPosition = satPosition;
ci.VideoPid = rawChannel.VideoPid;
ci.ServiceId = rawChannel.ServiceId;
ci.ServiceType = rawChannel.ServiceType;
ci.TransportStreamId = rawChannel.TransportStreamId;
ci.OriginalNetworkId = rawChannel.OriginalNetworkId;
ci.Favorites = rawChannel.Favorites;
ci.Encrypted = rawChannel.Encrypted;
ci.Lock = rawChannel.Lock;
ci.ShortName = rawChannel.ShortName;
if (transponder != null)
{
ci.Transponder = transponder;
ci.FreqInMhz = transponder.FrequencyInMhz;
ci.ChannelOrTransponder = this.GetTransponderChannelNumber((ushort)transponder.FrequencyInMhz);
ci.SymbolRate = transponder.SymbolRate;
ci.Polarity = transponder.Polarity;
}
this.DataRoot.AddChannel(channelList, ci);
}
#endregion
#region GetTransponderChannelNumber()
private string GetTransponderChannelNumber(ushort frequency)
{
int nr = LookupData.Instance.GetTransponderNumber(frequency);
return nr <= 0 ? "" : nr.ToString("d3");
}
#endregion
#region ReadAstraHdPlusChannels()
private unsafe void ReadAstraHdPlusChannels(ZipFile zip)
private void ReadAstraHdPlusChannels(ZipFile zip)
{
this.hdplusFileContent = ReadFileContent(zip, "map-AstraHDPlusD");
if (hdplusFileContent == null || c.hdplusChannelLength == 0)
return;
this.DataRoot.AddChannelList(this.hdplusChannels);
fixed (byte* ptr = hdplusFileContent)
int entrySize = c.hdplusChannelLength;
int count = hdplusFileContent.Length / entrySize;
DataMapping mapping = hdplusMappings.GetMapping(entrySize);
mapping.SetDataPtr(hdplusFileContent, 0);
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
int entrySize = c.hdplusChannelLength;
int count = hdplusFileContent.Length / entrySize;
DvbSChannelDataMapping mapping = hdplusMappings.GetMapping(entrySize);
mapping.DataPtr = ptr;
for (int slotIndex = 0; slotIndex < count; slotIndex++)
{
MapDvbsChannel(this.hdplusChannels, mapping, slotIndex);
mapping.Next();
}
SatChannel ci = new SatChannel(slotIndex, mapping, this.DataRoot);
if (ci.InUse)
this.hdplusChannels.AddChannel(ci);
mapping.BaseOffset += entrySize;
}
}
#endregion
@@ -562,13 +501,9 @@ namespace ChanSort.Plugin.ScmFile
}
#endregion
private unsafe delegate void UpdateFunc(ChannelInfo channelInfo, byte* fileContent);
#region Save()
public override unsafe void Save(string tvOutputFile, string csvOutputFile, UnsortedChannelMode unsortedMode)
public override void Save(string tvOutputFile, string csvOutputFile)
{
this.unsortedChannelMode = unsortedMode;
if (tvOutputFile != this.FileName)
{
File.Copy(this.FileName, tvOutputFile);
@@ -577,19 +512,19 @@ namespace ChanSort.Plugin.ScmFile
using (ZipFile zip = new ZipFile(tvOutputFile))
{
zip.BeginUpdate();
this.SaveChannels(zip, "map-AirA", this.avbtChannels, this.UpdateAnalogChannel, ref this.avbtFileContent);
this.SaveChannels(zip, "map-CableA", this.avbcChannels, this.UpdateAnalogChannel, ref this.avbcFileContent);
this.SaveChannels(zip, "map-AirD", this.dvbtChannels, this.UpdateDvbctChannel, ref this.dvbtFileContent);
this.SaveChannels(zip, "map-CableD", this.dvbcChannels, this.UpdateDvbctChannel, ref this.dvbcFileContent);
this.SaveChannels(zip, "map-SateD", this.dvbsChannels, this.UpdateDvbsChannel, ref this.dvbsFileContent);
this.SaveChannels(zip, "map-AstraHDPlusD", this.hdplusChannels, this.UpdateHdPlusChannel, ref this.hdplusFileContent);
this.SaveChannels(zip, "map-AirA", this.avbtChannels, ref this.avbtFileContent);
this.SaveChannels(zip, "map-CableA", this.avbcChannels, ref this.avbcFileContent);
this.SaveChannels(zip, "map-AirD", this.dvbtChannels, ref this.dvbtFileContent);
this.SaveChannels(zip, "map-CableD", this.dvbcChannels, ref this.dvbcFileContent);
this.SaveChannels(zip, "map-SateD", this.dvbsChannels, ref this.dvbsFileContent);
this.SaveChannels(zip, "map-AstraHDPlusD", this.hdplusChannels, ref this.hdplusFileContent);
zip.CommitUpdate();
}
}
#endregion
#region SaveChannels()
private unsafe void SaveChannels(ZipFile zip, string fileName, ChannelList channels, UpdateFunc updateChannel, ref byte[] fileContent)
private void SaveChannels(ZipFile zip, string fileName, ChannelList channels, ref byte[] fileContent)
{
if (fileContent == null)
return;
@@ -598,7 +533,7 @@ namespace ChanSort.Plugin.ScmFile
string tempFilePath = Path.GetTempFileName();
using (var stream = new FileStream(tempFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
this.WriteChannels(channels, updateChannel, fileContent, stream);
this.WriteChannels(channels, fileContent, stream);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
int size = (int)new FileInfo(tempFilePath).Length;
@@ -611,122 +546,15 @@ namespace ChanSort.Plugin.ScmFile
#endregion
#region WriteChannels()
private unsafe void WriteChannels(ChannelList list, UpdateFunc updateChannel, byte[] fileContent, FileStream stream)
private void WriteChannels(ChannelList list, byte[] fileContent, FileStream stream)
{
fixed (byte* ptr = fileContent)
foreach (var channel in list.Channels)
{
int maxSlot = 0;
foreach (var channel in list.Channels.OrderBy(ChannelComparer))
{
if (channel.RecordIndex < 0) // channel only exists in reference list
continue;
int newProgNr;
if (channel.NewProgramNr == 0 && this.unsortedChannelMode == UnsortedChannelMode.Hide)
newProgNr = 0;
else
{
newProgNr = channel.NewProgramNr != 0 ? channel.NewProgramNr : ++maxSlot;
if (newProgNr > maxSlot)
maxSlot = channel.NewProgramNr;
}
var channels = new List<ChannelInfo>();
channels.Add(channel);
channels.AddRange(channel.Duplicates);
foreach (var channelInstance in channels)
{
channelInstance.OldProgramNr = newProgNr;
updateChannel(channelInstance, ptr);
}
}
stream.Write(fileContent, 0, fileContent.Length);
#if false
if (count == 0 || count%padToPageSize != 0)
{
byte[] padding = new byte[(padToPageSize - count%padToPageSize) * entrySize];
stream.Write(padding, 0, padding.Length);
}
#endif
channel.UpdateRawData();
channel.OldProgramNr = channel.NewProgramNr;
}
}
#endregion
#region UpdateAnalogChannel()
private unsafe void UpdateAnalogChannel(ChannelInfo channel, byte* ptr)
{
AnalogChannelDataMapping raw = analogMappings.GetMapping(c.avbtChannelLength);
int startOffset = channel.RecordIndex * raw.DataLength;
raw.DataPtr = ptr + startOffset;
raw.ProgramNr = (ushort)channel.OldProgramNr;
raw.Favorites = channel.Favorites;
raw.Lock = channel.Lock;
raw.Checksum = CalcChecksum(raw.DataPtr, raw.DataLength);
}
#endregion
#region UpdateDvbctChannel()
private unsafe void UpdateDvbctChannel(ChannelInfo channel, byte* ptr)
{
DvbCtChannelDataMapping raw = dvbctMappings.GetMapping(c.dvbtChannelLength);
int startOffset = channel.RecordIndex * raw.DataLength;
raw.DataPtr = ptr + startOffset;
raw.ProgramNr = (ushort)channel.OldProgramNr;
raw.Favorites = channel.Favorites;
raw.Lock = channel.Lock;
raw.Checksum = CalcChecksum(raw.DataPtr, raw.DataLength);
}
#endregion
#region UpdateDvbsChannel()
private unsafe void UpdateDvbsChannel(ChannelInfo channel, byte* ptr)
{
DvbSChannelDataMapping raw = dvbsMappings.GetMapping(c.dvbsChannelLength);
int startOffset = channel.RecordIndex*raw.DataLength;
raw.DataPtr = (ptr + startOffset);
raw.ProgramNr = (ushort)channel.OldProgramNr;
raw.Favorites = channel.Favorites;
raw.Lock = channel.Lock;
raw.Checksum = CalcChecksum(raw.DataPtr, raw.DataLength);
}
#endregion
#region UpdateHdPlusChannel()
private unsafe void UpdateHdPlusChannel(ChannelInfo channel, byte* ptr)
{
DvbSChannelDataMapping raw = hdplusMappings.GetMapping(c.hdplusChannelLength);
int startOffset = channel.RecordIndex * raw.DataLength;
raw.DataPtr = (ptr + startOffset);
raw.ProgramNr = (ushort)channel.OldProgramNr;
raw.Favorites = channel.Favorites;
raw.Lock = channel.Lock;
raw.Checksum = CalcChecksum(raw.DataPtr, raw.DataLength);
}
#endregion
#region CalcChecksum()
private static unsafe byte CalcChecksum(byte* ptr, int length)
{
byte checksum = 0;
for (int i = 1; i < length; i++)
checksum += *ptr++;
return checksum;
}
#endregion
#region ChannelComparer()
private string ChannelComparer(ChannelInfo channel)
{
if (channel.NewProgramNr != 0)
return "A" + channel.NewProgramNr.ToString("d4");
if (channel.OldProgramNr != 0)
{
if (this.unsortedChannelMode == UnsortedChannelMode.AppendInOrder)
return "B" + channel.OldProgramNr.ToString("d4");
return "B" + channel.Name;
}
return "Z";
stream.Write(fileContent, 0, fileContent.Length);
}
#endregion

View File

@@ -1,6 +1,6 @@
using ChanSort.Api;
namespace ChanSort.Plugin.ScmFile
namespace ChanSort.Loader.ScmFile
{
public class ScmSerializerPlugin : ISerializerPlugin
{

View File

@@ -1,97 +0,0 @@
using System.Runtime.InteropServices;
namespace ChanSort.Plugin.ScmFile
{
[StructLayout(LayoutKind.Sequential, Pack=1)]
unsafe struct SatDataBase
{
public byte Magic0x55;
public int SatelliteNr;
public int TransponderCount;
public fixed ushort Name[64];
public int IsWest;
public int LongitudeTimes10;
};
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TransponderDataBase
{
public byte Magic0x55;
public int TransponderNr;
public int SatelliteNr;
public int Frequency;
public int SymbolRate;
public int IsVerticalPolarity;
public int Modulation;
public int CodeRate;
public int Unknown1;
public int Unknown2;
public int Unknown3;
public int Unknown4;
};
#if false
[StructLayout(LayoutKind.Sequential, Pack=1)]
unsafe struct MapSateD
{
public ushort ChannelNumber;
public ushort VideoPid;
public ushort Pid;
public byte Mpeg4;
public byte Unknown8;
public ushort Unknown9;
public ushort Unknonw11;
public ushort Unknown13;
public byte ServiceType;
public byte Unknown16;
public ushort ServiceId;
public ushort TransponderNr;
public ushort SatelliteNr;
public ushort Unknown23;
public ushort TransportStreamId;
public ushort Unknown27;
public ushort OriginalNetworkId;
public ushort Unknown31;
public ushort HRes;
public ushort VRes;
public fixed ushort NameInBigEndianUtf16[51];
public ushort Bouquet;
public byte Unknown141;
public byte Locked;
public byte Favorites;
public byte ChecksumCSeries;
public fixed byte Padding [28];
}
#endif
#if false
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct MapAirD
{
public ushort ChannelNumber;
public ushort VideoPid;
public ushort PcrPid;
public ushort ServiceId;
public ushort Status;
public ushort Unknown11;
public ushort Qam;
public byte ServiceType;
public byte Codec;
public fixed byte Unknown17 [7];
public byte Encrypted;
public fixed byte Unknown25 [3];
public ushort Frequency;
public ushort LogicalChannelNumber;
public fixed byte Unknown31 [2];
public ushort SymbolRate;
public ushort Bouquet;
public ushort TransportStreamId;
public fixed byte Unknown39 [5];
public fixed ushort NameInBigEndianUtf16[100];
public byte Unknown244;
public ushort Locked;
public byte FavoritesX79;
public byte ChecksumBSeries;
public fixed byte PaddingCSeries [292 - 248];
}
#endif
}