diff --git a/ChanSort.Api/Controller/CsvFileSerializer.cs b/ChanSort.Api/Controller/CsvFileSerializer.cs index 47f1997..1b9e3f5 100644 --- a/ChanSort.Api/Controller/CsvFileSerializer.cs +++ b/ChanSort.Api/Controller/CsvFileSerializer.cs @@ -1,106 +1,154 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; namespace ChanSort.Api { + /// + /// Reads a reference list from a .csv file with the format + /// [dummy1],ProgramNr,[dummy2],UID,ChannelName[,SignalSource,FavAndFlags] + /// public class CsvFileSerializer { - private static readonly char[] Separators = new[] { ',', ';', '\t' }; + private readonly HashSet clearedLists = new HashSet(); + private readonly DataRoot dataRoot; + private readonly string fileName; + + #region ctor() + public CsvFileSerializer(string fileName, DataRoot dataRoot) + { + this.fileName = fileName; + this.dataRoot = dataRoot; + } + #endregion #region Load() - public void Load(string fileName, DataRoot dataRoot) + public void Load() { - foreach (var list in dataRoot.ChannelLists) - { - foreach (var channel in list.Channels) - channel.NewProgramNr = 0; - } - + this.clearedLists.Clear(); using (var stream = new StreamReader(fileName)) - { - ReadChannelsFromStream(stream, dataRoot); - } + this.ReadChannelsFromStream(stream); } #endregion #region ReadChannelsFromStream() - public static void ReadChannelsFromStream(TextReader stream, DataRoot dataRoot) + public void ReadChannelsFromStream(TextReader stream) { - string line; - while ((line = stream.ReadLine()) != null) + int lineNr = 0; + string line = ""; + try { - ParseChannel(line, dataRoot); + while ((line = stream.ReadLine()) != null) + { + ++lineNr; + this.ReadChannel(line); + } + } + catch (Exception ex) + { + throw new FileLoadException(string.Format("Error in reference file line #{0}: {1}", lineNr, line), ex); } } #endregion - #region ParseChannel() + #region ReadChannel() - private static void ParseChannel(string line, DataRoot dataRoot) + private void ReadChannel(string line) { - var parts = line.Split(Separators); - if (parts.Length < 5) return; - int index, slot, transportStreamId; - if (!int.TryParse(parts[0], out index)) return; - if (!int.TryParse(parts[1], out slot)) return; - if (!int.TryParse(parts[2], out transportStreamId)) return; - string uid = parts[3].Replace("\"", ""); - SignalSource signalSource; - SignalType signalType; - if (!GetSignalSourceAndType(ref slot, uid, parts, out signalSource, out signalType)) + var parts = CsvFile.Parse(line, ','); + if (parts.Count < 5) return; + int programNr; + if (!int.TryParse(parts[1], out programNr)) return; + string uid = parts[3]; + SignalSource signalSource = GetSignalSource(ref programNr, uid, parts); + if (signalSource == 0) return; - string name = parts[4].Replace("\"", ""); - ChannelList channelList = dataRoot.GetChannelList(signalSource, signalType, true); - + string name = parts[4]; + ChannelList channelList = this.GetInitiallyClearedChannelList(signalSource); + if (channelList == null) + return; IEnumerable channels = FindChannels(channelList, name, uid); var channel = channels == null ? null : channels.FirstOrDefault(c => c.NewProgramNr == 0); if (channel != null) - channel.NewProgramNr = slot; - else { - channel = new ChannelInfo(signalSource, signalType, uid, slot, name); - channel.TransportStreamId = transportStreamId; + channel.NewProgramNr = programNr; + if (parts.Count >= 7) + ApplyFlags(channel, parts[6]); + } + else if (parts.Count >= 6) // create proxy channel when using the new ref-list format + { + channel = new ChannelInfo(signalSource, uid, programNr, name); channelList.AddChannel(channel); } } + #endregion - private static bool GetSignalSourceAndType(ref int slot, string uid, string[] parts, out SignalSource signalSource, out SignalType signalType) + #region GetSignalSource() + private static SignalSource GetSignalSource(ref int slot, string uid, IList parts) { // new lists store a bitmask which defines the type of channel and list it came from - if (parts.Length >= 6) + if (parts.Count >= 6 && parts[5].Length >= 4) { - signalSource = (SignalSource)int.Parse(parts[5]); - signalType = (SignalType)((int)signalSource & (int)SignalType.Mixed); - return true; + SignalSource s = 0; + string code = parts[5]; + if (code[0] == 'A') s |= SignalSource.Analog; + else if (code[0] == 'D') s |= SignalSource.Digital; + + if (code[1] == 'A') s |= SignalSource.Antenna; + else if (code[1] == 'C') s |= SignalSource.Cable; + else if (code[1] == 'S') s |= SignalSource.Sat; + + if (code[2] == 'T') s |= SignalSource.Tv; + else if (code[2] == 'R') s |= SignalSource.Radio; + + s |= (SignalSource) (int.Parse(code.Substring(3)) << 12); + return s; } // compatibility for older lists - signalSource = 0; - signalType = 0; + bool isTv = slot < 0x4000; + slot &= 0x3FFFF; + SignalSource signalSource; switch (uid[0]) { case 'S': signalSource = SignalSource.DvbS; break; case 'C': signalSource = SignalSource.DvbCT; break; case 'A': signalSource = SignalSource.AnalogCT; break; case 'H': signalSource = SignalSource.HdPlusD; break; - default: return false; + default: return 0; } - signalType = slot < 0x4000 ? SignalType.Tv : SignalType.Radio; - signalSource |= (SignalSource)signalType; - slot &= 0x3FFFF; - return true; + signalSource |= isTv ? SignalSource.Tv : SignalSource.Radio; + return signalSource; } #endregion - #region FindChannels() - private static IEnumerable FindChannels(ChannelList channelList, string name, string uid) + #region GetInitiallyClearedChannelList() + private ChannelList GetInitiallyClearedChannelList(SignalSource signalSource) { + var channelList = dataRoot.GetChannelList(signalSource); + if (channelList == null) + return null; + if (!this.clearedLists.Contains(channelList)) + { + foreach (var channel in channelList.Channels) + channel.NewProgramNr = 0; + this.clearedLists.Add(channelList); + } + return channelList; + } + #endregion + + #region FindChannels() + private IEnumerable FindChannels(ChannelList channelList, string name, string uid) + { + // if there's only a single channel with the given name, use it regardless of UID (allows for a changed freq/tranpsonder) IList list = channelList.GetChannelByName(name).ToList(); if (list.Count == 1) return list; @@ -109,8 +157,8 @@ namespace ChanSort.Api if (uid.StartsWith("C") && (uidParts = uid.Split('-')).Length <= 4) { // older CSV files didn't use the Transponder as part of the UID, which is necessary - // to distinguish between identical channels (onid,tsid,sid) received on multiple transponders - // (e.g. from differnt regional DVB-T transmitters) + // to distinguish between DVB-T channels with identical (onid,tsid,sid), which may be received + // from multiple regional transmitters on different transponders int onid = int.Parse(uidParts[1]); int tsid = int.Parse(uidParts[2]); int sid = int.Parse(uidParts[3]); @@ -126,27 +174,90 @@ namespace ChanSort.Api } #endregion + #region ApplyFlags() + private void ApplyFlags(ChannelInfo channel, string flags) + { + channel.Lock = false; + channel.Skip = false; + channel.Hidden = false; + + foreach (char c in flags) + { + switch (c) + { + case '1': channel.Favorites |= Favorites.A; break; + case '2': channel.Favorites |= Favorites.B; break; + case '3': channel.Favorites |= Favorites.C; break; + case '4': channel.Favorites |= Favorites.D; break; + case '5': channel.Favorites |= Favorites.E; break; + case 'L': channel.Lock = true; break; + case 'S': channel.Skip = true; break; + case 'H': channel.Hidden = true; break; + case 'D': channel.IsDeleted = true; break; + } + } + } + #endregion + #region Save() - public void Save(string fileName, DataRoot dataRoot, UnsortedChannelMode unsortedChannelMode) + public void Save() { using (StreamWriter stream = new StreamWriter(fileName)) { foreach (var channelList in dataRoot.ChannelLists) { - int radioMask = channelList.SignalType == SignalType.Radio ? 0x4000 : 0; foreach (var channel in channelList.Channels.Where(ch => ch.NewProgramNr != 0).OrderBy(ch => ch.NewProgramNr)) { - string line = string.Format("{0},{1},{2},{3},\"{4}\"", - channel.RecordIndex, - channel.NewProgramNr | radioMask, - channel.TransportStreamId, + string line = string.Format("{0},{1},{2},{3},\"{4}\",{5},{6}", + "", // past: channel.RecordIndex, + channel.NewProgramNr, + "", // past: channel.TransportStreamId, channel.Uid, - channel.Name); + channel.Name, + this.EncodeSignalSource(channel.SignalSource), + this.EncodeFavoritesAndFlags(channel)); stream.WriteLine(line); } } } } #endregion + + #region EncodeSignalSource() + private object EncodeSignalSource(SignalSource signalSource) + { + StringBuilder sb = new StringBuilder(); + if ((signalSource & SignalSource.Analog) != 0) sb.Append('A'); + else sb.Append('D'); + + if ((signalSource & SignalSource.Antenna) != 0) sb.Append('A'); + else if ((signalSource & SignalSource.Cable) != 0) sb.Append('C'); + else sb.Append('S'); + + if ((signalSource & SignalSource.Radio) != 0) sb.Append('R'); + else sb.Append('T'); + + sb.Append((int)signalSource >> 12); + return sb.ToString(); + } + #endregion + + #region EncodeFavoritesAndFlags() + private string EncodeFavoritesAndFlags(ChannelInfo channel) + { + StringBuilder sb = new StringBuilder(); + if ((channel.Favorites & Favorites.A) != 0) sb.Append('1'); + if ((channel.Favorites & Favorites.B) != 0) sb.Append('2'); + if ((channel.Favorites & Favorites.C) != 0) sb.Append('3'); + if ((channel.Favorites & Favorites.D) != 0) sb.Append('4'); + if ((channel.Favorites & Favorites.E) != 0) sb.Append('5'); + if (channel.Lock) sb.Append('L'); + if (channel.Skip) sb.Append('S'); + if (channel.Hidden) sb.Append('H'); + if (channel.IsDeleted) sb.Append('D'); + return sb.ToString(); + } + + #endregion } } diff --git a/ChanSort.Api/Model/ChannelInfo.cs b/ChanSort.Api/Model/ChannelInfo.cs index 0bd59dd..402d2a3 100644 --- a/ChanSort.Api/Model/ChannelInfo.cs +++ b/ChanSort.Api/Model/ChannelInfo.cs @@ -13,7 +13,6 @@ namespace ChanSort.Api public virtual bool IsDeleted { get; set; } public SignalSource SignalSource { get; protected set; } - public SignalType SignalType { get; protected set; } public int RecordIndex { get; set; } public int RecordOrder { get; set; } public int OldProgramNr { get; set; } @@ -50,10 +49,9 @@ namespace ChanSort.Api /// /// Constructor for exiting TV channel /// - public ChannelInfo(SignalSource source, SignalType type, int index, int oldProgNr, string name) + public ChannelInfo(SignalSource source, int index, int oldProgNr, string name) { this.SignalSource = source; - this.SignalType = type; this.RecordIndex = index; this.RecordOrder = index; this.OldProgramNr = oldProgNr; @@ -64,15 +62,9 @@ namespace ChanSort.Api /// /// Constructor for reference list channels which no longer exist in TV list /// - /// - /// - /// - /// - /// - public ChannelInfo(SignalSource source, SignalType type, string uid, int newProgNr, string name) + public ChannelInfo(SignalSource source, string uid, int newProgNr, string name) { this.SignalSource = source; - this.SignalType = type; this.Uid = uid; this.NewProgramNr = newProgNr; this.Name = name; @@ -89,10 +81,8 @@ namespace ChanSort.Api { if ((this.SignalSource & SignalSource.Digital) == 0) this.uid = "A-0-" + (int)(this.FreqInMhz*20) + "-0"; - else if (this.SignalSource == SignalSource.DvbS) + else if ((this.SignalSource & SignalSource.Sat) != 0) this.uid = "S" + this.SatPosition + "-" + this.OriginalNetworkId + "-" + this.TransportStreamId + "-" + this.ServiceId; - else if (this.SignalSource == SignalSource.HdPlusD) - this.uid = "H" + this.OriginalNetworkId + "-" + this.ServiceId; else this.uid = "C-" + this.OriginalNetworkId + "-" + this.TransportStreamId + "-" + this.ServiceId + "-" + this.ChannelOrTransponder; } diff --git a/ChanSort.Api/Model/ChannelList.cs b/ChanSort.Api/Model/ChannelList.cs index 48211f2..cd9a4a2 100644 --- a/ChanSort.Api/Model/ChannelList.cs +++ b/ChanSort.Api/Model/ChannelList.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text; using System.Linq; namespace ChanSort.Api @@ -8,7 +7,6 @@ namespace ChanSort.Api public class ChannelList { private readonly SignalSource source; - private readonly SignalType type; private readonly IList channels = new List(); private readonly Dictionary> channelByUid = new Dictionary>(); private readonly Dictionary channelByProgNr = new Dictionary(); @@ -17,49 +15,19 @@ namespace ChanSort.Api private int duplicateUidCount; private int duplicateProgNrCount; - public ChannelList(SignalSource source, SignalType type) + public ChannelList(SignalSource source, string caption) { this.source = source; - this.type = type; + this.ShortCaption = caption; } + public string ShortCaption { get; private set; } public SignalSource SignalSource { get { return this.source; } } - public SignalType SignalType { get { return this.type; } } public IList Channels { get { return this.channels; } } public int Count { get { return channels.Count; } } public int DuplicateUidCount { get { return duplicateUidCount; } } public int DuplicateProgNrCount { get { return duplicateProgNrCount; } } - #region ShortCaption - public string ShortCaption - { - get - { - StringBuilder sb = new StringBuilder(); - switch (this.source) - { - case SignalSource.AnalogC: sb.Append("Analog Cable"); break; - case SignalSource.AnalogT: sb.Append("Analog Antenna"); break; - case SignalSource.AnalogCT: sb.Append("Analog Cable/Antenna"); break; - case SignalSource.DvbC: sb.Append("DVB-C"); break; - case SignalSource.DvbT: sb.Append("DVB-T"); break; - case SignalSource.DvbCT: sb.Append("DVB-C/T"); break; - case SignalSource.DvbS: sb.Append("DVB-S"); break; - case SignalSource.HdPlusD: sb.Append("Astra HD Plus"); break; - default: sb.Append(this.source.ToString()); break; - } - switch (this.type) - { - case SignalType.Tv: sb.Append(" - TV"); break; - case SignalType.Radio: sb.Append(" - Radio"); break; - case SignalType.Mixed: break; - default: sb.Append(this.type.ToString()); break; - } - return sb.ToString(); - } - } - #endregion - #region Caption public string Caption { @@ -85,23 +53,7 @@ namespace ChanSort.Api { IList others; if (this.channelByUid.TryGetValue(ci.Uid, out others)) - { ++duplicateUidCount; - ChannelInfo twin = others.FirstOrDefault(c => c.OldProgramNr == ci.OldProgramNr); - if (twin != null) - { - string warning = null; - if (ci.OldProgramNr != 0) - { - warning = string.Format(Resources.ChannelList_AddChannel__DuplicateUid, - this.ShortCaption, ci.Name, twin.RecordIndex, twin.OldProgramNr, ci.RecordIndex, - ci.OldProgramNr); - } - twin.Duplicates.Add(ci); - ci.OldProgramNr = 0; - return warning; - } - } else { others = new List(); diff --git a/ChanSort.Api/Model/DataRoot.cs b/ChanSort.Api/Model/DataRoot.cs index e55c0dd..215a830 100644 --- a/ChanSort.Api/Model/DataRoot.cs +++ b/ChanSort.Api/Model/DataRoot.cs @@ -62,21 +62,24 @@ namespace ChanSort.Api #region GetChannelList() - public ChannelList GetChannelList(SignalSource signalSource, SignalType signalType, bool createIfNotExists) + public ChannelList GetChannelList(SignalSource criteriaMask) { foreach (var list in this.channelLists) { - if ((list.SignalSource&SignalSource.Digital) != (signalSource&SignalSource.Digital)) // match digital/analog + uint searchMask = (uint)criteriaMask; + uint listMask = (uint) list.SignalSource; + + if ((listMask & 0x000F & searchMask) == 0) // digital/analog continue; - if (((int)list.SignalSource & 0x0F & (int)signalSource) == 0) // match any of cable/terrestrial/satellite + if ((listMask & 0x00F0 & searchMask) == 0) // air/cable/sat continue; - if (list.SignalType == signalType || list.SignalType == SignalType.Mixed) // match radio/tv/any - return list; + if ((listMask & 0x0F00 & searchMask) == 0) // tv/radio + continue; + if ((listMask & 0xF000) != (searchMask & 0xF000)) // preset list + continue; + return list; } - ChannelList newList = new ChannelList(signalSource, signalType); - if (createIfNotExists) - this.AddChannelList(newList); - return newList; + return null; } #endregion } diff --git a/ChanSort.Api/Model/Enums.cs b/ChanSort.Api/Model/Enums.cs index 876e031..f46f796 100644 --- a/ChanSort.Api/Model/Enums.cs +++ b/ChanSort.Api/Model/Enums.cs @@ -2,6 +2,7 @@ namespace ChanSort.Api { + #region enum SignalSource /// /// Bitmask for channel and list classification. /// An individual channel can only have one bit of each group set. @@ -22,13 +23,14 @@ namespace ChanSort.Api // bit 9+10: TV/Radio Tv = 0x0100, Radio = 0x0200, + TvAndRadio= Tv|Radio, // bit 13-16: Preset list selector (AstraHD+, Freesat, TivuSat, CanalDigitalSat, ... for Samsung) - StandardSat = 0 << 24, - HdPlus = 1 << 24, - Freesat = 2 << 24, - TivuSat = 3 << 24, - CanalDigital = 4 << 24, + StandardSat = 0 << 12, + AstraHdPlus = 1 << 12, + Freesat = 2 << 12, + TivuSat = 3 << 12, + CanalDigital = 4 << 12, AnalogC=Analog + Cable, AnalogT=Analog + Antenna, @@ -37,18 +39,26 @@ namespace ChanSort.Api DvbT= Digital + Antenna, DvbCT= Digital + Cable + Antenna, DvbS= Digital + Sat, - HdPlusD = Digital + HdPlus + HdPlusD = Digital + Sat + AstraHdPlus } - - public enum SignalType { Tv = SignalSource.Tv, Radio = SignalSource.Radio, Mixed = SignalSource.Tv|SignalSource.Radio } + #endregion [Flags] public enum Favorites : byte { A = 0x01, B = 0x02, C = 0x04, D = 0x08, E = 0x10 } public enum UnsortedChannelMode { - AppendInOrder, - AppendAlphabetically, - Hide + AppendInOrder=0, + AppendAlphabetically=1, + Hide=2 } + + public enum DvbServiceType + { + SdTv = 1, + Radio = 2, + Data = 12, + HdTv = 25, + Option = 211 + }; } diff --git a/ChanSort.Api/Utils/CsvFile.cs b/ChanSort.Api/Utils/CsvFile.cs index 9ad4147..d8991d7 100644 --- a/ChanSort.Api/Utils/CsvFile.cs +++ b/ChanSort.Api/Utils/CsvFile.cs @@ -34,6 +34,7 @@ namespace ChanSort.Api continue; } inQuote = !inQuote; + continue; } token.Append(ch); } diff --git a/ChanSort.Loader.ScmFile/AnalogChannel.cs b/ChanSort.Loader.ScmFile/AnalogChannel.cs index ec1c014..1dae412 100644 --- a/ChanSort.Loader.ScmFile/AnalogChannel.cs +++ b/ChanSort.Loader.ScmFile/AnalogChannel.cs @@ -9,9 +9,11 @@ namespace ChanSort.Loader.ScmFile #region ctor() - public AnalogChannel(int slot, SignalSource signalSource, DataMapping mapping, decimal freq, int favoriteNotSetValue) : + public AnalogChannel(int slot, bool isCable, DataMapping mapping, decimal freq, int favoriteNotSetValue) : base(mapping, favoriteNotSetValue) { + var signalSource = SignalSource.Analog | SignalSource.Tv; + signalSource |= isCable ? SignalSource.Cable : SignalSource.Antenna; this.InitCommonData(slot, signalSource, mapping); this.FreqInMhz = (decimal)mapping.GetFloat(_Frequency); // C,D,E series have the value in the data record diff --git a/ChanSort.Loader.ScmFile/DigitalChannel.cs b/ChanSort.Loader.ScmFile/DigitalChannel.cs index bf68cf0..fda6e4a 100644 --- a/ChanSort.Loader.ScmFile/DigitalChannel.cs +++ b/ChanSort.Loader.ScmFile/DigitalChannel.cs @@ -7,10 +7,12 @@ namespace ChanSort.Loader.ScmFile { private const string _ChannelOrTransponder = "offChannelTransponder"; - public DigitalChannel(int slot, SignalSource signalSource, DataMapping data, + public DigitalChannel(int slot, bool isCable, DataMapping data, IDictionary transpFreq, int favoriteNotSetValue) : base(data, favoriteNotSetValue) { + var signalSource = SignalSource.Digital; + signalSource |= isCable ? SignalSource.Cable : SignalSource.Antenna; this.InitCommonData(slot, signalSource, data); this.InitDvbData(data); diff --git a/ChanSort.Loader.ScmFile/SatChannel.cs b/ChanSort.Loader.ScmFile/SatChannel.cs index 10d1bbd..e32649b 100644 --- a/ChanSort.Loader.ScmFile/SatChannel.cs +++ b/ChanSort.Loader.ScmFile/SatChannel.cs @@ -6,10 +6,10 @@ namespace ChanSort.Loader.ScmFile { private const string _TransponderIndex = "offTransponderIndex"; - public SatChannel(int slot, DataMapping data, DataRoot dataRoot, int favoriteNotSetValue) : + public SatChannel(int slot, SignalSource presetList, DataMapping data, DataRoot dataRoot, int favoriteNotSetValue) : base(data, favoriteNotSetValue) { - this.InitCommonData(slot, SignalSource.DvbS, data); + this.InitCommonData(slot, SignalSource.DvbS | presetList, data); if (!this.InUse) return; diff --git a/ChanSort.Loader.ScmFile/ScmChannelBase.cs b/ChanSort.Loader.ScmFile/ScmChannelBase.cs index 303cd09..172a4b6 100644 --- a/ChanSort.Loader.ScmFile/ScmChannelBase.cs +++ b/ChanSort.Loader.ScmFile/ScmChannelBase.cs @@ -53,7 +53,6 @@ namespace ChanSort.Loader.ScmFile 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(); @@ -96,15 +95,11 @@ namespace ChanSort.Loader.ScmFile 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; + if (this.ServiceType == (int)DvbServiceType.Radio) + this.SignalSource |= SignalSource.Radio; + else + this.SignalSource |= SignalSource.Tv; } #endregion diff --git a/ChanSort.Loader.ScmFile/ScmSerializer.cs b/ChanSort.Loader.ScmFile/ScmSerializer.cs index 6c4af5f..5d213e2 100644 --- a/ChanSort.Loader.ScmFile/ScmSerializer.cs +++ b/ChanSort.Loader.ScmFile/ScmSerializer.cs @@ -10,36 +10,27 @@ 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 modelConstants = new Dictionary(); private readonly MappingPool analogMappings = new MappingPool("Analog"); private readonly MappingPool dvbctMappings = new MappingPool("DVB-C/T"); private readonly MappingPool dvbsMappings = new MappingPool("DVB-S"); - private readonly MappingPool hdplusMappings = new MappingPool("AstraHDPlus"); + private readonly MappingPool hdplusMappings = new MappingPool("AstraHD+"); private readonly MappingPool analogFineTuneMappings = new MappingPool("FineTune"); private readonly MappingPool ptccableMappings = new MappingPool("PTC"); private readonly MappingPool transponderMappings = new MappingPool("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); - private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT, SignalType.Mixed); - private readonly ChannelList dvbsChannels = new ChannelList(SignalSource.DvbS, SignalType.Mixed); - private readonly ChannelList hdplusChannels = new ChannelList(SignalSource.HdPlusD, SignalType.Mixed); + + private readonly ChannelList avbtChannels = new ChannelList(SignalSource.AnalogT|SignalSource.TvAndRadio, "analog Air"); + private readonly ChannelList avbcChannels = new ChannelList(SignalSource.AnalogC|SignalSource.TvAndRadio, "analog Cable"); + private readonly ChannelList dvbtChannels = new ChannelList(SignalSource.DvbT | SignalSource.Tv, "digital Air"); + private readonly ChannelList dvbcChannels = new ChannelList(SignalSource.DvbC | SignalSource.TvAndRadio, "digital Cable"); + private readonly ChannelList dvbsChannels = new ChannelList(SignalSource.DvbS | SignalSource.TvAndRadio, "Satellite"); + private readonly ChannelList hdplusChannels = new ChannelList(SignalSource.HdPlusD | SignalSource.TvAndRadio, "Astra HD+"); + private readonly Dictionary avbtFrequency = new Dictionary(); private readonly Dictionary avbcFrequency = new Dictionary(); private readonly Dictionary dvbcFrequency = new Dictionary(); private readonly Dictionary dvbtFrequency = new Dictionary(); + private byte[] avbtFileContent; private byte[] avbcFileContent; private byte[] dvbtFileContent; @@ -323,7 +314,8 @@ namespace ChanSort.Loader.ScmFile #region MapAnalogChannel() private void MapAnalogChannel(DataMapping rawChannel, int slotIndex, ChannelList list, decimal freq) { - AnalogChannel ci = new AnalogChannel(slotIndex, list.SignalSource, rawChannel, freq, c.favoriteNotSetValue); + bool isCable = (list.SignalSource & SignalSource.Cable) != 0; + AnalogChannel ci = new AnalogChannel(slotIndex, isCable, rawChannel, freq, c.favoriteNotSetValue); if (!ci.InUse) return; @@ -363,14 +355,15 @@ namespace ChanSort.Loader.ScmFile data = ReadFileContent(zip, fileName); if (data == null) return; - + + bool isCable = (list.SignalSource & SignalSource.Cable) != 0; this.DataRoot.AddChannelList(list); DataMapping rawChannel = dvbctMappings.GetMapping(entrySize); rawChannel.SetDataPtr(data, 0); int count = data.Length / entrySize; for (int slotIndex = 0; slotIndex < count; slotIndex++) { - DigitalChannel ci = new DigitalChannel(slotIndex, list.SignalSource, rawChannel, frequency, c.favoriteNotSetValue); + DigitalChannel ci = new DigitalChannel(slotIndex, isCable, rawChannel, frequency, c.favoriteNotSetValue); if (ci.OldProgramNr != 0) this.DataRoot.AddChannel(list, ci); @@ -456,7 +449,7 @@ namespace ChanSort.Loader.ScmFile mapping.SetDataPtr(dvbsFileContent, 0); for (int slotIndex = 0; slotIndex < count; slotIndex++) { - SatChannel ci = new SatChannel(slotIndex, mapping, this.DataRoot, c.favoriteNotSetValue); + SatChannel ci = new SatChannel(slotIndex, SignalSource.StandardSat, mapping, this.DataRoot, c.favoriteNotSetValue); if (ci.InUse) this.DataRoot.AddChannel(this.dvbsChannels, ci); @@ -479,9 +472,9 @@ namespace ChanSort.Loader.ScmFile mapping.SetDataPtr(hdplusFileContent, 0); for (int slotIndex = 0; slotIndex < count; slotIndex++) { - SatChannel ci = new SatChannel(slotIndex, mapping, this.DataRoot, c.favoriteNotSetValue); + SatChannel ci = new SatChannel(slotIndex, SignalSource.AstraHdPlus, mapping, this.DataRoot, c.favoriteNotSetValue); if (ci.InUse) - this.hdplusChannels.AddChannel(ci); + this.DataRoot.AddChannel(this.hdplusChannels, ci); mapping.BaseOffset += entrySize; } } diff --git a/ChanSort.Loader.TllFile/TllChannelBase.cs b/ChanSort.Loader.TllFile/TllChannelBase.cs index 22db9b1..123f42c 100644 --- a/ChanSort.Loader.TllFile/TllChannelBase.cs +++ b/ChanSort.Loader.TllFile/TllChannelBase.cs @@ -43,9 +43,8 @@ namespace ChanSort.Loader.TllFile protected void InitCommonData(int slot, SignalSource signalSource, DataMapping data) { this.RecordIndex = slot; - this.SignalSource = signalSource; var nr = data.GetWord(_ProgramNr); - this.SignalType = this.GetSignalType(nr); + this.SignalSource = signalSource | ((nr & 0x4000) == 0 ? SignalSource.Tv : SignalSource.Radio); this.OldProgramNr = (nr & 0x3FFF); this.ParseNames(); @@ -72,15 +71,6 @@ namespace ChanSort.Loader.TllFile } #endregion - #region GetSignalType() - protected SignalType GetSignalType(uint programNr) - { - if ((programNr & 0x4000) != 0) - return SignalType.Radio; - return SignalType.Tv; - } - #endregion - #region ParseNames() private void ParseNames() { @@ -98,7 +88,7 @@ namespace ChanSort.Loader.TllFile public override void UpdateRawData() { mapping.SetDataPtr(this.rawData, this.baseOffset); - mapping.SetWord(_ProgramNr, this.NewProgramNr + (this.SignalType == SignalType.Radio ? 0x4000 : 0)); + mapping.SetWord(_ProgramNr, this.NewProgramNr | ((this.SignalSource & SignalSource.Radio) != 0 ? 0x4000 : 0)); mapping.SetWord(_ProgramNr2, (mapping.GetWord(_ProgramNr2) & 0x0003) | (this.NewProgramNr << 2)); if (this.IsNameModified) { diff --git a/ChanSort.Loader.TllFile/TllFileSerializer.cs b/ChanSort.Loader.TllFile/TllFileSerializer.cs index 3d30e59..8b3a6b6 100644 --- a/ChanSort.Loader.TllFile/TllFileSerializer.cs +++ b/ChanSort.Loader.TllFile/TllFileSerializer.cs @@ -20,10 +20,16 @@ namespace ChanSort.Loader.TllFile private readonly string ERR_wrongChecksum = Resource.TllFileSerializer_ERR_wrongChecksum; private readonly string ERR_dupeChannel = Resource.TllFileSerializer_ERR_dupeChannel; + private readonly Dictionary satConfigs = new Dictionary(); private readonly MappingPool actMappings = new MappingPool("Analog and DVB-C/T"); private readonly MappingPool dvbsMappings = new MappingPool("DVB-S"); private readonly MappingPool firmwareMappings = new MappingPool("Firmware"); - private readonly Dictionary satConfigs = new Dictionary(); + + private readonly ChannelList atvChannels = new ChannelList(SignalSource.AnalogCT | SignalSource.Tv, "Analog TV"); + private readonly ChannelList dtvChannels = new ChannelList(SignalSource.DvbCT | SignalSource.Tv, "DTV"); + private readonly ChannelList radioChannels = new ChannelList(SignalSource.DvbCT | SignalSource.Radio, "Radio"); + private readonly ChannelList satTvChannels = new ChannelList(SignalSource.DvbS | SignalSource.Tv, "Sat-DTV"); + private readonly ChannelList satRadioChannels = new ChannelList(SignalSource.DvbS | SignalSource.Radio, "Sat-Radio"); private byte[] fileContent; @@ -60,7 +66,6 @@ namespace ChanSort.Loader.TllFile #region ctor() public TllFileSerializer(string inputFile) : base(inputFile) { - this.Features.ChannelNameEdit = true; this.Features.EraseChannelData = true; this.Features.FileInformation = true; @@ -74,6 +79,12 @@ namespace ChanSort.Loader.TllFile }; this.ReadConfigurationFromIniFile(); + + this.DataRoot.AddChannelList(atvChannels); + this.DataRoot.AddChannelList(dtvChannels); + this.DataRoot.AddChannelList(radioChannels); + this.DataRoot.AddChannelList(satTvChannels); + this.DataRoot.AddChannelList(satRadioChannels); } #endregion @@ -235,7 +246,7 @@ namespace ChanSort.Loader.TllFile actMapping.SetDataPtr(fileContent, off); ChannelInfo ci = channelFactory(i, actMapping); - var list = this.DataRoot.GetChannelList(ci.SignalSource, ci.SignalType, true); + var list = this.DataRoot.GetChannelList(ci.SignalSource); this.DataRoot.AddChannel(list, ci); off += recordSize; @@ -415,7 +426,7 @@ namespace ChanSort.Loader.TllFile ++this.deletedChannelsSoft; else { - var list = this.DataRoot.GetChannelList(ci.SignalSource, ci.SignalType, true); + var list = this.DataRoot.GetChannelList(ci.SignalSource); var dupes = list.GetChannelByUid(ci.Uid); if (dupes.Count == 0) { @@ -531,14 +542,9 @@ namespace ChanSort.Loader.TllFile #region ReorderActChannelsPhysically() private void ReorderActChannelsPhysically() { - var analogTv = this.DataRoot.GetChannelList(SignalSource.AnalogCT, SignalType.Tv, false); - var analogRadio = this.DataRoot.GetChannelList(SignalSource.AnalogCT, SignalType.Radio, false); - var analog = analogTv.Channels.Union(analogRadio.Channels).ToList(); - this.ReorderChannelData(this.analogBlockOffset + 8, this.actChannelSize, this.analogChannelCount, analog); + this.ReorderChannelData(this.analogBlockOffset + 8, this.actChannelSize, this.analogChannelCount, this.atvChannels.Channels); - var dvbCtTv = this.DataRoot.GetChannelList(SignalSource.DvbCT, SignalType.Tv, false); - var dvbCtRadio = this.DataRoot.GetChannelList(SignalSource.DvbCT, SignalType.Radio, false); - var dvbCt = dvbCtTv.Channels.Union(dvbCtRadio.Channels).ToList(); + var dvbCt = this.dtvChannels.Channels.Union(this.radioChannels.Channels).ToList(); this.ReorderChannelData(this.dvbctBlockOffset + 8, this.actChannelSize, this.dvbctChannelCount, dvbCt); } #endregion diff --git a/ChanSort.Loader.TllFile/TllFileSerializer.sql.cs b/ChanSort.Loader.TllFile/TllFileSerializer.sql.cs index 88f5c37..6265e9a 100644 --- a/ChanSort.Loader.TllFile/TllFileSerializer.sql.cs +++ b/ChanSort.Loader.TllFile/TllFileSerializer.sql.cs @@ -63,8 +63,8 @@ from channel c inner join chanseq s on s.listid=c.listid and s.slot=c.slot if (this.dvbsBlockSize == 0) return; - var list = this.DataRoot.GetChannelList(SignalSource.DvbS, SignalType.Tv, false); - if (list == null) + var list = this.DataRoot.GetChannelList(SignalSource.DvbS|SignalSource.Tv); + if (list == null || list.Count == 0) return; using (var conn = SqlClientFactory.Instance.CreateConnection()) diff --git a/ChanSort/MainForm.cs b/ChanSort/MainForm.cs index 369ead5..f2fe227 100644 --- a/ChanSort/MainForm.cs +++ b/ChanSort/MainForm.cs @@ -39,7 +39,6 @@ namespace ChanSort.Ui private ISerializerPlugin currentPlugin; private SerializerBase currentTvSerializer; private Editor editor; - private readonly CsvFileSerializer csvSerializer = new CsvFileSerializer(); private DataRoot dataRoot; private bool ignoreLanguageChange; private readonly string title; @@ -325,7 +324,10 @@ namespace ChanSort.Ui private void LoadCsvFile() { if (File.Exists(this.currentCsvFile)) - this.csvSerializer.Load(this.currentCsvFile, this.dataRoot); + { + var csvSerializer = new CsvFileSerializer(this.currentCsvFile, this.dataRoot); + csvSerializer.Load(); + } else { foreach (var list in this.dataRoot.ChannelLists) @@ -356,7 +358,10 @@ namespace ChanSort.Ui string ext = (Path.GetExtension(dlg.FileName) ?? "").ToLower(); if (ext == ".csv") - this.csvSerializer.Load(dlg.FileName, this.dataRoot); + { + var csvSerializer = new CsvFileSerializer(dlg.FileName, this.dataRoot); + csvSerializer.Load(); + } else if (ext == ".chl") { ChlFileSerializer loader = new ChlFileSerializer(); @@ -466,7 +471,8 @@ namespace ChanSort.Ui private void SaveReferenceFile() { - this.csvSerializer.Save(this.currentCsvFile, this.dataRoot, UnsortedChannelMode.Hide); + var csvSerializer = new CsvFileSerializer(this.currentCsvFile, this.dataRoot); + csvSerializer.Save(); } #endregion diff --git a/Test.Loader.TllFile/UnitTest1.cs b/Test.Loader.TllFile/UnitTest1.cs index 01d03fa..2297c96 100644 --- a/Test.Loader.TllFile/UnitTest1.cs +++ b/Test.Loader.TllFile/UnitTest1.cs @@ -94,7 +94,7 @@ namespace Test.Loader.TllFile var fileName = Path.GetFileName(file) ?? ""; int idx = fileName.IndexOf("-"); string key = idx < 0 ? fileName : fileName.Substring(0, idx); - var satChannelList = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.DvbS, ChanSort.Api.SignalType.Tv, false); + var satChannelList = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.DvbS|ChanSort.Api.SignalSource.Tv); key += "\t" + serializer.ACTChannelLength+ "\t"+serializer.HasDvbs+ "\t"+serializer.SatChannelLength+ @@ -119,9 +119,9 @@ namespace Test.Loader.TllFile ExpectedData exp; key = Path.GetFileName(Path.GetDirectoryName(file)) + "\\" + Path.GetFileName(file); this.expectedData.TryGetValue(key, out exp); - var analogTv = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.AnalogCT, ChanSort.Api.SignalType.Tv, false); - var dtvTv = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.DvbCT, ChanSort.Api.SignalType.Tv, false); - var satTv = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.DvbS, ChanSort.Api.SignalType.Tv, false); + var analogTv = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.AnalogCT|ChanSort.Api.SignalSource.Tv); + var dtvTv = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.DvbCT|ChanSort.Api.SignalSource.Tv); + var satTv = serializer.DataRoot.GetChannelList(ChanSort.Api.SignalSource.DvbS | ChanSort.Api.SignalSource.Tv); if (exp != null) { this.expectedData.Remove(key);