- Samsung J series: fixed deleting of channels

- LG GlobalClone: modified channel names were not written to the file
- LG GlobalClone: ask whether the conflicting xx*.TLL files should be
  renamed so that the TV can import the GlobalClone file.
- LG GlobalClone: improved support for old file format with may
  have caused errors due to invalid XML characters inside the file.
- Panasonic: re-enabled channel lists with gaps in the numbers
- Update-Check: looking for latest version at github.com
- Detecting corrupted files with 0 size or all bytes with value 0
- upgraded to latest DevExpress version
This commit is contained in:
hbeham
2015-09-19 23:24:31 +02:00
parent 43cfca4d0b
commit b0277bd4a3
30 changed files with 638 additions and 442 deletions

View File

@@ -19,6 +19,7 @@ namespace ChanSort.Loader.GlobalClone
private readonly DvbStringDecoder dvbStringDecoder = new DvbStringDecoder(Encoding.Default);
private string modelName;
private readonly Dictionary<int, string> satPositionByIndex = new Dictionary<int, string>();
private bool usesBinaryDataInUtf8Envelope = false;
#region ctor()
public GcSerializer(string inputFile) : base(inputFile)
@@ -35,7 +36,8 @@ namespace ChanSort.Loader.GlobalClone
#endregion
#region DisplayName
public override string DisplayName { get { return "LG GlobalClone loader"; } }
public override string DisplayName => "LG GlobalClone loader";
#endregion
@@ -47,8 +49,13 @@ namespace ChanSort.Loader.GlobalClone
try
{
this.doc = new XmlDocument();
using (var reader = new StreamReader(new FileStream(this.FileName, FileMode.Open), Encoding.UTF8))
string textContent = File.ReadAllText(this.FileName, Encoding.UTF8);
textContent = ReplaceInvalidXmlCharacters(textContent);
var settings = new XmlReaderSettings { CheckCharacters = false };
using (var reader = XmlReader.Create(new StringReader(textContent), settings))
{
doc.Load(reader);
}
}
catch
{
@@ -76,15 +83,17 @@ namespace ChanSort.Loader.GlobalClone
break;
}
}
this.Features.ChannelNameEdit = usesBinaryDataInUtf8Envelope ? ChannelNameEditMode.Analog : ChannelNameEditMode.All;
}
#endregion
#region ReadModelInfo()
private void ReadModelInfo(XmlNode modelInfoNode)
{
var txt = Resources.GcSerializer_ReadModelInfo_ModelWarning;
// show warning about broken import function in early webOS firmware
var regex = new System.Text.RegularExpressions.Regex(@"\d{2}([A-Z]{2})(\d{2})\d[0-9A-Z].*");
var series = "";
foreach (XmlNode child in modelInfoNode.ChildNodes)
{
switch (child.LocalName)
@@ -94,15 +103,26 @@ namespace ChanSort.Loader.GlobalClone
var match = regex.Match(this.modelName);
if (match.Success)
{
var series = match.Groups[1].Value;
series = match.Groups[1].Value;
if ((series == "LB" || series == "UB") && StringComparer.InvariantCulture.Compare(match.Groups[2].Value, "60") >= 0)
txt = Resources.GcSerializer_webOsFirmwareWarning;
MessageBox.Show(Resources.GcSerializer_webOsFirmwareWarning, "LG GlobalClone", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
break;
}
}
MessageBox.Show(txt, "LG GlobalClone editor", MessageBoxButtons.OK, MessageBoxIcon.Information);
// ask whether binary TLL file should be deleted
var dir = Path.GetDirectoryName(this.FileName) ?? ".";
var binTlls = Directory.GetFiles(dir, "xx" + series + "*.tll");
if (binTlls.Length > 0)
{
var txt = Resources.GcSerializer_ReadModelInfo_ModelWarning;
if (MessageBox.Show(txt, "LG GlobalClone", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
foreach (var file in binTlls)
File.Move(file, file + "_bak");
}
}
}
#endregion
@@ -303,10 +323,12 @@ namespace ChanSort.Loader.GlobalClone
if (bytes.Length == 0 || bytes[0] < 0xC0)
return input;
this.usesBinaryDataInUtf8Envelope = true;
// older GlobalClone files look like as if the <vchName> is Chinese, but it's a weired "binary inside UTF8 envelope" encoding:
// A 3 byte UTF-8 envelope is used to encode 2 input bytes: 1110aaaa 10bbbbcc 10ccdddd represents the 16bit little endian integer aaaabbbbccccdddd, which represents bytes ccccdddd, aaaabbbb
// If a remaining byte is >= 0x80, it is encoded in a 2 byte UTF-8 envelope: 110000aa 10aabbbb represents the byte aaaabbbb
// If a remaining byte is < 0x80, it is encoded directly into a 1 byte UTF-8 char
// If a remaining byte is < 0x80, it is encoded directly into a 1 byte UTF-8 char. (This can cause invalid XML files for values < 0x20.)
using (MemoryStream ms = new MemoryStream(40))
{
for (int i = 0, c = bytes.Length; i < c; i++)
@@ -349,7 +371,9 @@ namespace ChanSort.Loader.GlobalClone
{
var ch = channel as GcChannel;
if (ch == null) continue; // ignore proxy channels from reference lists
var nameBytes = Encoding.UTF8.GetBytes(ch.Name);
bool nameNeedsEncoding = nameBytes.Length != ch.Name.Length;
foreach (XmlNode node in ch.XmlNode.ChildNodes)
{
switch (node.LocalName)
@@ -360,6 +384,18 @@ namespace ChanSort.Loader.GlobalClone
nr |= 0x4000;
node.InnerText = nr.ToString();
break;
case "hexVchName":
if (channel.IsNameModified)
node.InnerText = (nameNeedsEncoding ? "15" : "") + Tools.HexEncode(nameBytes); // 0x15 = DVB encoding indicator for UTF-8
break;
case "notConvertedLengthOfVchName":
if (channel.IsNameModified)
node.InnerText = ((nameNeedsEncoding ? 1 : 0) + ch.Name.Length).ToString();
break;
case "vchName":
if (channel.IsNameModified)
node.InnerText = nameNeedsEncoding ? "" : ch.Name;
break;
case "isInvisable":
node.InnerText = ch.Hidden ? "1" : "0";
break;
@@ -392,11 +428,13 @@ namespace ChanSort.Loader.GlobalClone
settings.NewLineHandling = NewLineHandling.Replace;
settings.OmitXmlDeclaration = true;
settings.IndentChars = "";
settings.CheckCharacters = false;
using (StringWriter sw = new StringWriter())
using (XmlWriter xw = XmlWriter.Create(sw, settings))
{
doc.Save(xw);
var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n\r\n" + sw;
string xml = RestoreInvalidXmlCharacters(sw.ToString());
xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n\r\n" + xml;
File.WriteAllText(tvOutputFile, xml, settings.Encoding);
}
}
@@ -432,5 +470,56 @@ namespace ChanSort.Loader.GlobalClone
}
#endregion
#region ReplaceInvalidXmlCharacters()
private string ReplaceInvalidXmlCharacters(string input)
{
StringBuilder output = new StringBuilder();
foreach (var c in input)
{
if (c >= ' ' || c == '\r' || c == '\n' || c == '\t')
output.Append(c);
else
output.AppendFormat("&#x{0:d}{1:d};", c >> 4, c & 0x0F);
}
return output.ToString();
}
#endregion
#region RestoreInvalidXmlCharacters()
private string RestoreInvalidXmlCharacters(string input)
{
StringBuilder output = new StringBuilder();
int prevIdx = 0;
while(true)
{
int nextIdx = input.IndexOf("&#", prevIdx);
if (nextIdx < 0)
break;
output.Append(input, prevIdx, nextIdx - prevIdx);
int numBase = 10;
char inChar;
int outChar = 0;
for (nextIdx += 2; (inChar=input[nextIdx]) != ';'; nextIdx++)
{
if (inChar == 'x' || inChar == 'X')
numBase = 16;
else
outChar = outChar*numBase + HexNibble(inChar);
}
var binChar = (char)outChar;
output.Append(binChar);
prevIdx = nextIdx + 1;
}
output.Append(input, prevIdx, input.Length - prevIdx);
return output.ToString();
}
private int HexNibble(char hexDigit)
{
return hexDigit >= '0' && hexDigit <= '9' ? hexDigit - '0' : (Char.ToUpper(hexDigit) - 'A') + 10;
}
#endregion
}
}

View File

@@ -1,7 +1,7 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -61,14 +61,8 @@ namespace ChanSort.Loader.GlobalClone {
}
/// <summary>
/// Looks up a localized string similar to Before you waste your time...
///
///...make sure that your LG TV can load this file (without modifications).
///Some LG TVs export 2 files, a GlobalClone00001.TLL and file like xxLB550U-ZA00001.TLL.
///
///If you have both file types, it&apos;s likely that the TV can only load the xxLB550U-ZA00001.TLL and you should edit that file instead.
///
///If your TV only exports a single &quot;Clone&quot; TLL, you&apos;re good to continue!.
/// Looks up a localized string similar to Your TV will only import the GlobalClone file when there are no files named xx*.TLL in the same directory.
///Do you want ChanSort to rename the conflicting files?.
/// </summary>
internal static string GcSerializer_ReadModelInfo_ModelWarning {
get {

View File

@@ -118,14 +118,8 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="GcSerializer_ReadModelInfo_ModelWarning" xml:space="preserve">
<value>Bevor Sie Ihre Zeit verschwenden...
...überprüfen Sie, ob Ihr LG Gerät diese Datei (unmodifiziert) einlesen kann.
Einige LG Geräte exportieren 2 Dateien: eine "Clone" TLL und eine Datei ähnlich wie xxLB550U-ZA00001.TLL.
Wenn Ihr Gerät 2 Dateien erzeugt, kann es vermutlich nur die xxLB550U-ZA00001.TLL einlesen und Sie sollten deshalb jene Datei bearbeiten.
Wenn Ihr Gerät nur diese "Clone" Datei erstellt, können Sie mit der Bearbeitung fortfahren.</value>
<value>Ihr TV Gerät importiert die GlobalClone Datei nur dann, wenn keine Dateien mit Namen xx*.TLL auf dem USB-Stick sind.
Soll ChanSort die störenden Dateien jetzt umbenennen?</value>
</data>
<data name="GcSerializer_webOsFirmwareWarning" xml:space="preserve">
<value>HINWEIS:

View File

@@ -99,14 +99,8 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="GcSerializer_ReadModelInfo_ModelWarning" xml:space="preserve">
<value>Before you waste your time...
...make sure that your LG TV can load this file (without modifications).
Some LG TVs export 2 files, a GlobalClone00001.TLL and file like xxLB550U-ZA00001.TLL.
If you have both file types, it's likely that the TV can only load the xxLB550U-ZA00001.TLL and you should edit that file instead.
If your TV only exports a single "Clone" TLL, you're good to continue!</value>
<value>Your TV will only import the GlobalClone file when there are no files named xx*.TLL in the same directory.
Do you want ChanSort to rename the conflicting files?</value>
</data>
<data name="GcSerializer_webOsFirmwareWarning" xml:space="preserve">
<value>ATTENTION: