- added unit tests for Enigma2 and Grundig loaders

- added round-trip unit test for all loaders to check reordering channels and favorites, saving and reloading
- internal code clean-up regarding different favorite list modes (none vs. flags vs. ordered per source vs. mixed source)
This commit is contained in:
Horst Beham
2021-03-14 22:13:22 +01:00
parent f5010439cb
commit 5705a435b4
104 changed files with 19262 additions and 316 deletions

View File

@@ -5,10 +5,12 @@ namespace ChanSort.Api
{
public class ChannelInfo
{
private const int MaxFavListsWithFlags = 8;
private string uid;
private string serviceTypeName;
private int newProgramNr;
public virtual bool IsDeleted { get; set; }
public SignalSource SignalSource { get; set; }
public string Source { get; set; }
@@ -65,6 +67,10 @@ namespace ChanSort.Api
public string SatPosition { get; set; }
public Transponder Transponder { get; set; }
/// <summary>
/// Defines whether favorite lists have individual ordering (FavIndex, OldFavIndex) or if they use the main channel number (Favorites bitmask)
/// </summary>
public FavoritesMode FavMode { get; set; }
/// <summary>
/// Bitmask in which favorite lists the channel is included
/// </summary>
@@ -304,60 +310,68 @@ namespace ChanSort.Api
#region GetPosition(), SetPosition(), ChangePosition()
/// <summary>
/// Gets the new channel number in the main channel list (index=0) or the various favorite lists (1-x)
/// Gets the new channel number in the main channel list (index=0) or the various favorite lists (1..x)
/// </summary>
public int GetPosition(int subListIndex)
{
return subListIndex < 0 ? -1 : subListIndex == 0 ? this.NewProgramNr : subListIndex - 1 < this.FavIndex.Count ? this.FavIndex[subListIndex - 1] : -1;
}
public int GetPosition(int subListIndex) => this.GetNewOrOldPosition(subListIndex, this.NewProgramNr, this.FavIndex);
/// <summary>
/// Gets the original channel number in the main channel list (index=0) or the various favorite lists (1-x)
/// Gets the original channel number in the main channel list (index=0) or the various favorite lists (1..x)
/// </summary>
public int GetOldPosition(int subListIndex)
{
return subListIndex < 0 ? -1 : subListIndex == 0 ? this.OldProgramNr : subListIndex - 1 < this.OldFavIndex.Count ? this.OldFavIndex[subListIndex - 1] : -1;
}
public int GetOldPosition(int subListIndex) => this.GetNewOrOldPosition(subListIndex, this.OldProgramNr, this.OldFavIndex);
/// <summary>
/// Sets the new channel number in the main channel list (index=0) or the various favorite lists (1-x)
/// </summary>
public void SetPosition(int subListIndex, int newPos)
private int GetNewOrOldPosition(int subListIndex, int progNr, List<int> fav)
{
if (subListIndex < 0)
return;
if (subListIndex < 0)
return -1;
if (subListIndex == 0)
this.NewProgramNr = newPos;
else
{
for (int i = this.FavIndex.Count; i < subListIndex; i++)
this.FavIndex.Add(-1);
this.FavIndex[subListIndex - 1] = newPos;
int mask = 1 << (subListIndex - 1);
if (newPos == -1)
this.Favorites &= (Favorites)~mask;
else
this.Favorites |= (Favorites)mask;
}
return progNr;
if (this.FavMode == FavoritesMode.None)
return -1;
if (this.FavMode == FavoritesMode.Flags)
return subListIndex > MaxFavListsWithFlags ? -1 : ((uint)this.Favorites & (1 << (subListIndex - 1))) == 0 ? 0 : progNr;
if (subListIndex - 1 >= fav.Count)
return -1;
return fav[subListIndex - 1];
}
/// <summary>
/// Sets the original channel number in the main channel list (index=0) or the various favorite lists (1-x)
/// Sets the new channel number in the main channel list (index=0) or the various favorite lists (1..x)
/// </summary>
public void SetOldPosition(int subListIndex, int oldPos)
public void SetPosition(int subListIndex, int newPos) => this.SetNewOrOldPosition(subListIndex, newPos, n => this.NewProgramNr=n, this.FavIndex, f => this.Favorites = f);
/// <summary>
/// Sets the original channel number in the main channel list (index=0) or the various favorite lists (1..x)
/// </summary>
public void SetOldPosition(int subListIndex, int oldPos) => this.SetNewOrOldPosition(subListIndex, oldPos, n => this.OldProgramNr = n, this.OldFavIndex, null);
private void SetNewOrOldPosition(int subListIndex, int newPos, Action<int> setMainPosition, List<int> fav, Action<Favorites> setFavFlags)
{
if (subListIndex < 0)
return;
if (subListIndex == 0)
this.OldProgramNr = oldPos;
else
setMainPosition(newPos);
else if (this.FavMode != FavoritesMode.None)
{
for (int i = this.OldFavIndex.Count; i < subListIndex; i++)
this.OldFavIndex.Add(-1);
this.OldFavIndex[subListIndex - 1] = oldPos;
if (this.FavMode != FavoritesMode.Flags)
{
for (int i = fav.Count; i < subListIndex; i++)
fav.Add(-1);
fav[subListIndex - 1] = newPos;
}
if (setFavFlags != null && subListIndex <= MaxFavListsWithFlags)
{
int mask = 1 << (subListIndex - 1);
if (newPos == -1)
this.Favorites &= (Favorites) ~mask;
else
this.Favorites |= (Favorites) mask;
}
}
}
/// <summary>
/// Internal helper method to adjust the main or favorite program number by a delta value
/// </summary>
@@ -365,13 +379,19 @@ namespace ChanSort.Api
{
if (subListIndex == 0)
this.NewProgramNr += delta;
else
else if (this.FavMode != FavoritesMode.None)
{
for (int i = this.FavIndex.Count; i <= subListIndex; i++)
for (int i = this.FavIndex.Count; i < subListIndex; i++)
this.FavIndex.Add(-1);
this.FavIndex[subListIndex - 1] += delta;
}
}
#endregion
public void ResetFavorites()
{
this.FavIndex.Clear();
this.Favorites = 0;
}
}
}

View File

@@ -33,12 +33,15 @@ namespace ChanSort.Api
public string ShortCaption { get; set; }
public SignalSource SignalSource { get; }
public IList<ChannelInfo> Channels { get; } = new List<ChannelInfo>();
public int MaxFavLists { get; set; }
public int Count => Channels.Count;
public int DuplicateUidCount => duplicateUidCount;
public int DuplicateProgNrCount => duplicateProgNrCount;
public bool ReadOnly { get; set; }
public int MaxChannelNameLength { get; set; }
public int PresetProgramNrCount { get; private set; }
public IList<string> VisibleColumnFieldNames;
/// <summary>

View File

@@ -17,9 +17,10 @@ namespace ChanSort.Api
public bool IsEmpty => this.channelLists.Count == 0;
public bool NeedsSaving { get; set; }
public FavoritesMode FavoritesMode => this.loader.Features.FavoritesMode;
public Favorites SupportedFavorites => this.loader.Features.SupportedFavorites;
public bool SortedFavorites => this.loader.Features.SortedFavorites;
public bool MixedSourceFavorites => this.loader.Features.MixedSourceFavorites;
public bool SortedFavorites => this.loader.Features.FavoritesMode >= FavoritesMode.OrderedPerSource;
public bool MixedSourceFavorites => this.loader.Features.FavoritesMode == FavoritesMode.MixedSource;
public bool AllowGapsInFavNumbers => this.loader.Features.AllowGapsInFavNumbers;
public bool DeletedChannelsNeedNumbers => this.loader.Features.DeleteMode == SerializerBase.DeleteMode.FlagWithPrNr;
public bool CanSkip => this.loader.Features.CanSkipChannels;
@@ -67,7 +68,6 @@ namespace ChanSort.Api
public virtual void AddChannelList(ChannelList list)
{
this.channelLists.Add(list);
this.loader.Features.MixedSourceFavorites |= list.IsMixedSourceFavoritesList;
}
#endregion
@@ -110,22 +110,23 @@ namespace ChanSort.Api
#region ValidateAfterLoad()
public virtual void ValidateAfterLoad()
{
this.FavListCount = 0;
for (ulong m = (ulong)this.loader.Features.SupportedFavorites; m != 0; m >>= 1)
++this.FavListCount;
this.FavListCount = this.loader.Features.MaxFavoriteLists;
var favMode = this.FavoritesMode;
if (this.ChannelLists.Any(l => l.IsMixedSourceFavoritesList))
favMode = loader.Features.FavoritesMode = FavoritesMode.MixedSource;
foreach (var list in this.ChannelLists)
{
if (list.IsMixedSourceFavoritesList)
{
loader.Features.SortedFavorites = true; // all mixed source favorite lists must support ordering
continue;
}
// make sure that deleted channels have OldProgramNr = -1
bool hasPolarity = false;
foreach (var chan in list.Channels)
{
chan.FavMode = favMode; // required so that channels know how to handle favorites (as bitmasks or as indices)
if (chan.IsDeleted)
chan.OldProgramNr = -1;
else
@@ -144,12 +145,19 @@ namespace ChanSort.Api
#region ApplyCurrentProgramNumbers()
public void ApplyCurrentProgramNumbers()
{
// prevent setting OldPosition to -1 in lists that don't support sorted favorites, because it would clear the Favorites flags
int maxPos = this.SortedFavorites ? this.FavListCount : 0;
foreach (var list in this.ChannelLists)
{
foreach (var channel in list.Channels)
{
for (int i = 0; i <= this.FavListCount; i++)
channel.SetPosition(i, channel.GetOldPosition(i));
if (!list.IsMixedSourceFavoritesList)
channel.NewProgramNr = channel.OldProgramNr;
if (!this.MixedSourceFavorites || list.IsMixedSourceFavoritesList)
{
for (int i = 1; i <= maxPos; i++)
channel.SetPosition(i, channel.GetOldPosition(i));
}
}
}
}

View File

@@ -75,16 +75,32 @@ namespace ChanSort.Api
}
#endregion
#region enum Favorites
[Flags]
public enum Favorites : long { A = 0x01, B = 0x02, C = 0x04, D = 0x08, E = 0x10, F=0x20, G=0x40, H=0x80 }
public enum Favorites : byte { A = 0x01, B = 0x02, C = 0x04, D = 0x08, E = 0x10, F=0x20, G=0x40, H=0x80 }
#endregion
#region enum FavoritesMode
public enum FavoritesMode
{
NotInitialized = 0,
None = 1,
Flags = 2,
OrderedPerSource = 3,
MixedSource = 4
}
#endregion
#region enum UnsortedChannelMode
public enum UnsortedChannelMode
{
AppendInOrder=0,
AppendAlphabetically=1,
Delete=2
}
#endregion
#region ChannelNameEditMode
[Flags]
public enum ChannelNameEditMode
{
@@ -93,4 +109,5 @@ namespace ChanSort.Api
Digital = 0x02,
All = Analog|Digital
}
#endregion
}