diff --git a/source/ChanSort.Api/Model/ChannelList.cs b/source/ChanSort.Api/Model/ChannelList.cs index ae7fdbb..1157bb4 100644 --- a/source/ChanSort.Api/Model/ChannelList.cs +++ b/source/ChanSort.Api/Model/ChannelList.cs @@ -31,7 +31,7 @@ namespace ChanSort.Api } public string ShortCaption { get; set; } - public SignalSource SignalSource { get; } + public SignalSource SignalSource { get; set; } public IList Channels { get; } = new List(); public int Count => Channels.Count; diff --git a/source/ChanSort.Api/Utils/Tools.cs b/source/ChanSort.Api/Utils/Tools.cs index 73dbf57..3a7c6b4 100644 --- a/source/ChanSort.Api/Utils/Tools.cs +++ b/source/ChanSort.Api/Utils/Tools.cs @@ -82,11 +82,23 @@ namespace ChanSort.Api public static void MemCopy(byte[] source, int sourceIndex, byte[] dest, int destIndex, int count) { + if (destIndex + count > dest.Length) + count = dest.Length - destIndex; + if (count <= 0) + return; + if (sourceIndex + count > source.Length) + count = source.Length - sourceIndex; + if (count <= 0) + return; Array.Copy(source, sourceIndex, dest, destIndex, count); } public static void MemSet(this byte[] data, int offset, byte value, int count) { + if (offset + count > data.Length) + count = data.Length - offset; + if (count <= 0) + return; for (int i = 0; i < count; i++) data[offset++] = value; } diff --git a/source/ChanSort.Loader.DBM/ChanSort.Loader.DBM.ini b/source/ChanSort.Loader.DBM/ChanSort.Loader.DBM.ini index 9911cdd..9f4cc71 100644 --- a/source/ChanSort.Loader.DBM/ChanSort.Loader.DBM.ini +++ b/source/ChanSort.Loader.DBM/ChanSort.Loader.DBM.ini @@ -28,11 +28,13 @@ offProgNr=64 offLcn=66 offTransponderIndex=70 offServiceType=76 -;offSkip=79 -;maskSkip=0x08 -;offLock=79 -;maskLock=0x10 -;offFavorites=81 +offHide=77 +maskHide=0x04 +offSkip=77 +maskSkip=0x08 +offLock=77 +maskLock=0x10 +offFavorites=79 offTsid=96 offOnid=98 offSid=100 @@ -85,6 +87,8 @@ offLcn=66 offSatelliteIndex=70 offTransponderIndex=72 offServiceType=80 +offHide=81 +maskHide=0x04 offSkip=81 maskSkip=0x08 offLock=81 @@ -142,6 +146,8 @@ offLcn=66 offSatelliteIndex=70 offTransponderIndex=72 offServiceType=80 +offHide=81 +maskHide=0x04 offSkip=81 maskSkip=0x08 offLock=81 @@ -199,6 +205,8 @@ offLcn=66 offSatelliteIndex=70 offTransponderIndex=72 offServiceType=80 +offHide=81 +maskHide=0x04 offSkip=81 maskSkip=0x08 offLock=81 @@ -256,6 +264,8 @@ offLcn=66 offSatelliteIndex=70 offTransponderIndex=72 offServiceType=80 +offHide=81 +maskHide=0x04 offSkip=81 maskSkip=0x08 offLock=81 diff --git a/source/ChanSort.Loader.DBM/DbmSerializer.cs b/source/ChanSort.Loader.DBM/DbmSerializer.cs index bfddeea..4b5bd45 100644 --- a/source/ChanSort.Loader.DBM/DbmSerializer.cs +++ b/source/ChanSort.Loader.DBM/DbmSerializer.cs @@ -28,7 +28,7 @@ namespace ChanSort.Loader.DBM this.Features.ChannelNameEdit = ChannelNameEditMode.None; this.Features.CanSkipChannels = true; this.Features.CanLockChannels = true; - this.Features.CanHideChannels = false; + this.Features.CanHideChannels = true; this.Features.DeleteMode = DeleteMode.NotSupported; this.Features.CanHaveGaps = false; this.Features.FavoritesMode = FavoritesMode.Flags; @@ -64,8 +64,19 @@ namespace ChanSort.Loader.DBM throw LoaderException.Fail($"No configuration for .DBM files with size {info.Length} in .ini file"); this.isDvbS = sec.GetBool("isDvbS"); - if (!isDvbS) + if (isDvbS) + { + allChannels.ShortCaption = "DVB-S"; + allChannels.SignalSource &= ~SignalSource.MaskAntennaCableSat; + allChannels.SignalSource |= SignalSource.Sat; + } + else + { + allChannels.ShortCaption = "DVB-C"; + allChannels.SignalSource &= ~SignalSource.MaskAntennaCableSat; + allChannels.SignalSource |= SignalSource.Cable; allChannels.VisibleColumnFieldNames.Remove(nameof(ChannelInfo.Satellite)); + } this.data = File.ReadAllBytes(this.FileName); this.mapping = new DataMapping(sec); @@ -165,7 +176,11 @@ namespace ChanSort.Loader.DBM { if ((data[offBitmap + i / 8] & (1 << (i & 0x07))) != 0) { - var c = new ChannelInfo(SignalSource.Any, i, -1, null); + var serviceType = mapping.GetByte("offServiceType"); + var src = serviceType == 1 ? SignalSource.Tv : serviceType == 2 ? SignalSource.Radio : SignalSource.Data; + src |= SignalSource.Digital; + src |= isDvbS ? SignalSource.Sat : SignalSource.Cable; + var c = new ChannelInfo(src, i, -1, null); dec.GetChannelNames(data, mapping.BaseOffset + sec.GetInt("offName"), sec.GetInt("lenName"), out var longName, out var shortName); c.Name = longName; c.ShortName = shortName; @@ -175,9 +190,9 @@ namespace ChanSort.Loader.DBM c.ServiceId = mapping.GetWord("offSid"); c.PcrPid = mapping.GetWord("offPcrPid"); c.VideoPid = mapping.GetWord("offVideoPid"); + c.Hidden = mapping.GetFlag("Hide", false); c.Skip = mapping.GetFlag("Skip", false); c.Lock = mapping.GetFlag("Lock", false); - var serviceType = mapping.GetByte("offServiceType"); c.ServiceTypeName = serviceType == 1 ? "TV" : serviceType == 2 ? "Radio" : ""; var fav = mapping.GetByte("offFavorites"); @@ -220,6 +235,14 @@ namespace ChanSort.Loader.DBM continue; mapping.BaseOffset = baseOffset + (int)chan.RecordIndex * recordSize; mapping.SetWord("offProgNr", chan.NewProgramNr - 1); + mapping.SetFlag("Skip", chan.Skip); + mapping.SetFlag("Lock", chan.Lock); + mapping.SetFlag("Hide", chan.Hidden); + var fav = (int)mapping.GetByte("offFavorites"); + fav &= ~0x1D; + var newFav = (int)chan.Favorites; + fav |= (byte)((newFav & 0x01) | ((newFav & 0xFE) << 1)); // A=1, B=4, C=8, D=16 + mapping.SetByte("offFavorites", fav); } mapping.BaseOffset = 0; diff --git a/source/ChanSort.Loader.TCL/DtvDataSerializer.cs b/source/ChanSort.Loader.TCL/DtvDataSerializer.cs index 6ff32ee..89c29b7 100644 --- a/source/ChanSort.Loader.TCL/DtvDataSerializer.cs +++ b/source/ChanSort.Loader.TCL/DtvDataSerializer.cs @@ -1,11 +1,17 @@ -using System.Text; +#define Win10_TAR +#define TestBuild + +using System.Diagnostics; +using System.Text; using Microsoft.Data.Sqlite; using ChanSort.Api; +#if !Win10_TAR using SharpCompress.Archives; using SharpCompress.Archives.Tar; using SharpCompress.Common; using SharpCompress.Readers; using SharpCompress.Writers.Tar; +#endif namespace ChanSort.Loader.TCL { @@ -29,7 +35,11 @@ namespace ChanSort.Loader.TCL public DtvDataSerializer(string inputFile) : base(inputFile) { this.Features.ChannelNameEdit = ChannelNameEditMode.All; +#if TestBuild + this.Features.DeleteMode = DeleteMode.NotSupported; +#else this.Features.DeleteMode = DeleteMode.Physically; +#endif this.Features.CanSkipChannels = false; this.Features.CanLockChannels = false; this.Features.CanHideChannels = true; @@ -119,11 +129,22 @@ namespace ChanSort.Loader.TCL #region UntarToTempDir() private void UntarToTempDir() { - using var tar = TarArchive.Open(this.FileName); - var rdr = tar.ExtractAllEntries(); this.TempPath = Path.Combine(Path.GetTempPath(), "ChanSort_" + DateTime.Now.ToString("yyyyMMdd-HHmmss")); Directory.CreateDirectory(this.TempPath); + +#if Win10_TAR + var psi = new ProcessStartInfo("tar"); + psi.UseShellExecute = true; + psi.WindowStyle = ProcessWindowStyle.Hidden; + psi.WorkingDirectory = this.TempPath; + psi.Arguments = $"xf \"{this.FileName}\""; + var proc = Process.Start(psi); + proc.WaitForExit(); +#else + using var tar = TarArchive.Open(this.FileName); + var rdr = tar.ExtractAllEntries(); rdr.WriteAllToDirectory(this.TempPath, new ExtractionOptions { ExtractFullPath = true }); +#endif } #endregion @@ -171,7 +192,6 @@ namespace ChanSort.Loader.TCL using var conn = new SqliteConnection(satConnString); conn.Open(); using var cmd = conn.CreateCommand(); - this.RepairCorruptedDatabaseImage(cmd); cmd.CommandText = "SELECT name FROM sqlite_master WHERE type = 'table'"; using (var r = cmd.ExecuteReader()) @@ -195,21 +215,12 @@ namespace ChanSort.Loader.TCL using var conn = new SqliteConnection(dtvConnString); conn.Open(); using var cmd = conn.CreateCommand(); - this.RepairCorruptedDatabaseImage(cmd); this.ReadTransponders(cmd); this.ReadChannels(cmd); } #endregion - #region RepairCorruptedDatabaseImage() - private void RepairCorruptedDatabaseImage(SqliteCommand cmd) - { - cmd.CommandText = "REINDEX"; - cmd.ExecuteNonQuery(); - } - #endregion - #region ReadSatellites() private void ReadSatellites(SqliteCommand cmd) { @@ -327,13 +338,16 @@ left outer join CurCIOPSerType c on c.u8DtvRoute=p.u8DtvRoute conn.Open(); using var trans = conn.BeginTransaction(); using var cmd = conn.CreateCommand(); +#if TestBuild + SqliteCommand cmd2 = null; +#else using var cmd2 = conn.CreateCommand(); +#endif this.WriteChannels(cmd, cmd2, this.channels); trans.Commit(); cmd.Transaction = null; - this.RepairCorruptedDatabaseImage(cmd); } UpdateCrc(); @@ -346,17 +360,25 @@ left outer join CurCIOPSerType c on c.u8DtvRoute=p.u8DtvRoute #region WriteChannels() private void WriteChannels(SqliteCommand cmd, SqliteCommand cmdDelete, ChannelList channelList) { - cmd.CommandText = "update PrograminfoTbl set ProgNum=@nr, ServiceName=@name, unlockedFlag=@hide, EditFlag=(EditFlag & 0xFFFFFFFE) | @editflag where u32Index=@handle"; + cmd.CommandText = "update PrograminfoTbl set ProgNum=@nr" +#if !TestBuild + + ", ServiceName=@name, unlockedFlag=@hide, EditFlag=(EditFlag & 0xFFFFFFFE) | @editflag" +#endif + + " where u32Index=@handle"; cmd.Parameters.Add("@handle", SqliteType.Integer); cmd.Parameters.Add("@nr", SqliteType.Integer); - cmd.Parameters.Add("@name", SqliteType.Text); +#if !TestBuild + cmd.Parameters.Add("@name", SqliteType.Blob, 64); cmd.Parameters.Add("@hide", SqliteType.Integer); cmd.Parameters.Add("@editflag", SqliteType.Integer); +#endif cmd.Prepare(); - cmdDelete.CommandText = @"delete from PrograminfoTbl where u32Index=@handle;"; - cmdDelete.Parameters.Add("@handle", SqliteType.Integer); - cmdDelete.Prepare(); +#if !TestBuild + //cmdDelete.CommandText = @"delete from PrograminfoTbl where u32Index=@handle;"; + //cmdDelete.Parameters.Add("@handle", SqliteType.Integer); + //cmdDelete.Prepare(); +#endif foreach (ChannelInfo channel in channelList.Channels) { @@ -365,17 +387,24 @@ left outer join CurCIOPSerType c on c.u8DtvRoute=p.u8DtvRoute if (channel.IsDeleted) { +#if !TestBuild cmdDelete.Parameters["@handle"].Value = channel.RecordIndex; cmdDelete.ExecuteNonQuery(); +#endif } else { channel.UpdateRawData(); cmd.Parameters["@handle"].Value = channel.RecordIndex; cmd.Parameters["@nr"].Value = channel.NewProgramNr; - cmd.Parameters["@name"].Value = channel.Name; +#if !TestBuild + var bytes = Encoding.UTF8.GetBytes(channel.Name); + var blob = new byte[64]; + Tools.MemCopy(bytes, 0, blob, 0, 64); + cmd.Parameters["@name"].Value = blob; cmd.Parameters["@hide"].Value = channel.Hidden; cmd.Parameters["@editflag"].Value = channel.Favorites == 0 ? 0 : 0x0001; +#endif cmd.ExecuteNonQuery(); } } @@ -405,9 +434,19 @@ left outer join CurCIOPSerType c on c.u8DtvRoute=p.u8DtvRoute { // delete old .tar file and create a new one from temp dir File.Delete(this.FileName); +#if Win10_TAR + var psi = new ProcessStartInfo("tar"); + psi.UseShellExecute = true; + psi.WindowStyle = ProcessWindowStyle.Hidden; + psi.WorkingDirectory = this.TempPath; + psi.Arguments = $"cf \"{this.FileName}\" *"; + var proc = Process.Start(psi); + proc.WaitForExit(); +#else using var tar = TarArchive.Create(); tar.AddAllFromDirectory(this.TempPath); tar.SaveTo(this.FileName, new TarWriterOptions(CompressionType.None, true)); +#endif } #endregion } diff --git a/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/dbm.h b/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/dbm.h index fd13702..ac0a681 100644 --- a/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/dbm.h +++ b/source/Information/FileStructures_for_HHD_Hex_Editor_Neo/dbm.h @@ -42,6 +42,7 @@ enum e_Favorites : byte enum e_Flags : byte { + Hide=0x04, Skip=0x08, Lock=0x10 }; @@ -97,7 +98,7 @@ public struct DBM switch (GetDocumentSize()) { case 163772: - // TechniSat DVB-C vodafone.DBM + // TechniSat DVB-C TS_Programmliste_06_01.DBM satBitmapLength = 0; satRecordCount = 0; satRecordLength = 84; diff --git a/source/changelog.md b/source/changelog.md index 31613f3..2c0cc78 100644 --- a/source/changelog.md +++ b/source/changelog.md @@ -1,6 +1,12 @@ ChanSort Change Log =================== +2023-01-06_1450 +- .HDB: added support for "Hide"-flag, added Skip/Lock/Fav for TechniSat DVB-C file format + +2023-01-06_1420 +- fixed TCL .tar files: now saving names as BLOB instead of VARCHAR(64) + 2023-01-06 - added support for numerous .DBM file formats used by DVB-C and DVB-S receivers based on MStar chips. Known brands to use this format include Xoro, TechniSat, Strong, Comag and