- moved all files to a "source" subdirectory to tidy up the GitHub project page

- started to write a readme.md
This commit is contained in:
hbeham
2015-06-04 13:31:43 +02:00
parent 664235b1ed
commit d4318b13a5
397 changed files with 602 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
using System.IO;
namespace ChanSort
{
public static class BrowserHelper
{
public static void OpenUrl(string url)
{
OpenHtml(@"
<html>
<head>
<meta http-equiv='Refresh' content='0;" + url + @"'/>
</head>
</html>");
}
public static void OpenMail(string url)
{
OpenHtml(@"
<html>
<head>
<script language=""javascript"">
window.open(""" + url + @""");
window.close();
</script>
</head>
</html>");
}
public static void OpenHtml(string html)
{
try
{
string fileName = Path.GetTempFileName() + ".html";
File.WriteAllText(fileName, html);
System.Diagnostics.Process.Start(fileName);
}
catch
{
}
}
}
}

View File

@@ -0,0 +1,151 @@
using System.Text;
namespace ChanSort.Api
{
public unsafe class ChannelMappingBase : DataMapping
{
protected const string offInUse = "offInUse";
protected const string maskInUse = "maskInUse";
protected const string offProgramNr = "offProgramNr";
protected const string offName = "offName";
protected const string offNameLength = "offNameLength";
protected const string lenName = "lenName";
protected const string offSkip = "offSkip";
protected const string maskSkip = "maskSkip";
protected const string offLock = "offLock";
protected const string maskLock = "maskLock";
protected const string offLockSkipHide = "offHide";
protected const string maskHide = "maskHide";
protected const string offFavorites = "offFavorites";
private const string offDeleted = "offDeleted";
private const string maskDeleted = "maskDeleted";
#region ctor()
public ChannelMappingBase(IniFile.Section settings, int length, Encoding stringEncoding) :
base(settings, length, stringEncoding)
{
}
#endregion
#region InUse
public virtual bool InUse
{
get
{
var val = this.GetOffsets(offInUse);
return val.Length == 0 || this.GetFlag(offInUse, maskInUse);
}
}
#endregion
#region ProgramNr
public virtual ushort ProgramNr
{
get { return this.GetWord(offProgramNr); }
set { this.SetWord(offProgramNr, value); }
}
#endregion
#region NameLength
public virtual int NameLength
{
get
{
var off = this.GetOffsets(offNameLength);
if (off.Length > 0)
return this.GetWord(off[0]);
return MaxNameLength;
}
set { this.SetByte(offNameLength, (byte) value); }
}
#endregion
#region MaxNameLength
public virtual int MaxNameLength
{
get
{
var off = this.GetOffsets(lenName); // not an offset!
return off.Length > 0 ? off[0] : 0;
}
}
#endregion
#region Name
public virtual string Name
{
get { return this.GetString(offName, this.NameLength); }
// ReSharper disable ValueParameterNotUsed
set { }
// ReSharper restore ValueParameterNotUsed
}
#endregion
#region NamePtr
public virtual byte* NamePtr
{
get { return this.DataPtr + this.GetOffsets(offName)[0]; }
set
{
int maxLen = this.MaxNameLength - 1;
if (maxLen == 0)
maxLen = this.NameLength;
foreach (int off in this.GetOffsets(offName))
{
int i;
for (i = 0; i < maxLen && value[i] != 0; i++)
this.DataPtr[off + i] = value[i];
for (; i <= maxLen; i++)
this.DataPtr[off + i] = 0;
}
}
}
#endregion
#region ShortName
public virtual string ShortName { get; set; }
#endregion
#region Skip
public virtual bool Skip
{
get { return this.GetFlag(offSkip, maskSkip); }
set { this.SetFlag(offSkip, maskSkip, value); }
}
#endregion
#region Lock
public virtual bool Lock
{
get { return this.GetFlag(offLock, maskLock); }
set { this.SetFlag(offLock, maskLock, value); }
}
#endregion
#region Hide
public virtual bool Hide
{
get { return this.GetFlag(offLockSkipHide, maskHide); }
set { this.SetFlag(offLockSkipHide, maskHide, value); }
}
#endregion
#region Favorites
public virtual Favorites Favorites
{
get { return (Favorites) this.GetByte(offFavorites); }
set { this.SetByte(offFavorites, (byte) value); }
}
#endregion
#region IsDeleted
public virtual bool IsDeleted
{
get { return this.GetFlag(offDeleted, maskDeleted); }
set { this.SetFlag(offDeleted, maskDeleted, value); }
}
#endregion
}
}

View File

@@ -0,0 +1,62 @@
namespace ChanSort.Api
{
public static class Crc32
{
private const uint CrcMask = 0xFFFFFFFF;
private const uint CrcPoly = 0xEDB88320;
private static readonly uint[] crc32Table;
static Crc32()
{
crc32Table = InitCrc32Table();
}
#region InitCrc32Table()
private static uint[] InitCrc32Table()
{
var crcTable = new uint[256];
for (uint i = 0; i < 256; i++)
{
uint r = i;
for (uint j = 8; j > 0; j--)
{
if ((r & 1) == 1)
r = ((r >> 1) ^ CrcPoly);
else
r >>= 1;
}
crcTable[i] = r;
}
return crcTable;
}
#endregion
#region CalcCrc32()
public static uint CalcCrc32(byte[] block, int start, int length)
{
uint crc32 = CrcMask;
for (int i = 0; i < length; i++)
crc32 = crc32Table[(crc32 & 0xff) ^ block[start + i]] ^ (crc32 >> 8);
return crc32;
}
#endregion
#region Crack()
#if false
public static unsafe int Crack(byte* block, int maxLen, uint checksum)
{
uint crc32 = CrcMask;
for (int i = 0; i < maxLen; i++)
{
if (crc32 == checksum)
return i;
crc32 = crc32Table[(crc32 & 0xff) ^ block[i]] ^ (crc32 >> 8);
}
return 0;
}
#endif
#endregion
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
using System.Text;
namespace ChanSort.Api
{
public static class CsvFile
{
public static IList<string> Parse(string line, char separator)
{
if (line.EndsWith("\n")) line = line.Substring(0, line.Length - 1);
if (line.EndsWith("\r")) line = line.Substring(0, line.Length - 1);
List<string> tokens = new List<string>();
if (line.Length == 0)
return tokens;
bool inQuote = false;
StringBuilder token = new StringBuilder();
for(int i = 0, len=line.Length; i<len; i++)
{
char ch = line[i];
if (ch == separator && !inQuote)
{
tokens.Add(token.ToString());
token.Remove(0, token.Length);
continue;
}
if (ch == '"')
{
if (inQuote && i+1 < len && line[i+1] == '"')
{
token.Append('"');
++i;
continue;
}
inQuote = !inQuote;
continue;
}
token.Append(ch);
}
tokens.Add(token.ToString());
return tokens;
}
}
}

View File

@@ -0,0 +1,197 @@
using System;
using System.Text;
namespace ChanSort.Api
{
public class DataMapping
{
protected readonly IniFile.Section settings;
private int baseOffset;
private byte[] data { get; set; }
public Encoding DefaultEncoding { get; set; }
#region ctor()
public DataMapping(IniFile.Section settings)
{
this.settings = settings;
this.DefaultEncoding = Encoding.Default;
}
#endregion
#region SetDataPtr(), Data, BaseOffset
public void SetDataPtr(byte[] data, int baseOffset)
{
this.data = data;
this.baseOffset = baseOffset;
}
public byte[] Data { get { return this.data; } }
public int BaseOffset { get { return this.baseOffset; } set { this.baseOffset = value; } }
#endregion
#region GetOffsets()
public int[] GetOffsets(string key)
{
return settings.GetIntList(key);
}
#endregion
public IniFile.Section Settings { get { return this.settings; } }
#region Byte
public byte GetByte(string key)
{
var offsets = settings.GetIntList(key);
if (offsets.Length==0) return 0;
return this.data[baseOffset + offsets[0]];
}
public void SetByte(string key, int value)
{
var offsets = settings.GetIntList(key);
foreach (int offset in offsets)
this.data[baseOffset + offset] = (byte)value;
}
#endregion
#region Word
public ushort GetWord(string key)
{
var offsets = settings.GetIntList(key);
if (offsets.Length == 0) return 0;
return BitConverter.ToUInt16(this.data, baseOffset + offsets[0]);
}
public void SetWord(string key, int value)
{
var offsets = settings.GetIntList(key);
foreach (int offset in offsets)
{
this.data[baseOffset + offset + 0] = (byte)value;
this.data[baseOffset + offset + 1] = (byte)(value>>8);
}
}
#endregion
#region DWord
public long GetDword(string key)
{
var offsets = settings.GetIntList(key);
if (offsets.Length == 0) return 0;
return BitConverter.ToUInt32(this.data, baseOffset + offsets[0]);
}
public void SetDword(string key, long value)
{
var offsets = settings.GetIntList(key);
foreach (int offset in offsets)
{
this.data[baseOffset + offset + 0] = (byte)value;
this.data[baseOffset + offset + 1] = (byte)(value >> 8);
this.data[baseOffset + offset + 2] = (byte)(value >> 16);
this.data[baseOffset + offset + 3] = (byte)(value >> 24);
}
}
#endregion
#region Float
public float GetFloat(string key)
{
var offsets = settings.GetIntList(key);
if (offsets.Length == 0) return 0;
return BitConverter.ToSingle(this.data, baseOffset + offsets[0]);
}
public void SetFloat(string key, float value)
{
var offsets = settings.GetIntList(key);
var bytes = BitConverter.GetBytes(value);
foreach (int offset in offsets)
{
for (int i = 0; i < 4; i++)
this.data[baseOffset + offset + i] = bytes[i];
}
}
#endregion
#region GetFlag
public bool GetFlag(string key, bool defaultValue = false)
{
return GetFlag("off" + key, "mask" + key, defaultValue);
}
public bool GetFlag(string valueKey, string maskKey, bool defaultValue = false)
{
int mask = settings.GetInt(maskKey);
return GetFlag(valueKey, mask, defaultValue);
}
public bool GetFlag(string valueKey, int mask, bool defaultValue = false)
{
if (mask == 0) return defaultValue;
var offsets = settings.GetIntList(valueKey);
if (offsets.Length == 0) return defaultValue;
return (this.data[baseOffset + offsets[0]] & mask) == mask;
}
#endregion
#region SetFlag()
public void SetFlag(string key, bool value)
{
this.SetFlag("off" + key, "mask" + key, value);
}
public void SetFlag(string valueKey, string maskKey, bool value)
{
int mask = settings.GetInt(maskKey);
SetFlag(valueKey, mask, value);
}
public void SetFlag(string valueKey, int mask, bool value)
{
if (mask == 0) return;
var offsets = settings.GetIntList(valueKey);
foreach (var offset in offsets)
{
if (value)
this.data[baseOffset + offset] |= (byte)mask;
else
this.data[baseOffset + offset] &= (byte)~mask;
}
}
#endregion
#region GetString()
public string GetString(string key, int maxLen)
{
var offsets = settings.GetIntList(key);
if (offsets.Length == 0) return null;
int length = this.GetByte(key + "Length");
if (length == 0)
length = maxLen;
var encoding = this.DefaultEncoding;
return encoding.GetString(this.data, baseOffset + offsets[0], length).TrimEnd('\0');
}
#endregion
#region SetString()
public int SetString(string key, string text, int maxLen)
{
var bytes = this.DefaultEncoding.GetBytes(text);
int len = Math.Min(bytes.Length, maxLen);
foreach (var offset in settings.GetIntList(key))
{
Array.Copy(bytes, 0, this.data, baseOffset + offset, len);
for (int i = len; i < maxLen; i++)
this.data[baseOffset + offset + i] = 0;
}
return len;
}
#endregion
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.IO;
namespace ChanSort.Api
{
public static class DepencencyChecker
{
public static bool IsVc2010RedistPackageX86Installed()
{
object value = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\VC\VCRedist\x86",
"Installed", null);
return value != null && Convert.ToInt32(value) == 1;
}
public static void AssertVc2010RedistPackageX86Installed()
{
if (!IsVc2010RedistPackageX86Installed())
throw new FileLoadException("Please download and install the Microsoft Visual C++ 2010 Redistributable Package (x86)");
}
}
}

View File

@@ -0,0 +1,237 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace ChanSort.Api
{
#region Documentation
/*
ETSI EN 300 468
For one-byte character tables, the codes in the range 0x80 to 0x9F are assigned to control functions
as shown in Table A.1: Single byte control codes
Control code - Control code Description
0x80 to 0x85 reserved for future use
0x86 character emphasis on
0x87 character emphasis off
0x88 to 0x89 reserved for future use
0x8A CR/LF
0x8B to 0x9F user defined
A.2 Selection of character table
First byte value - Character code table - Table description - Reproduced in figure
0x01 ISO/IEC 8859-5 [27] Latin/Cyrillic alphabet A.2
0x02 ISO/IEC 8859-6 [28] Latin/Arabic alphabet A.3
0x03 ISO/IEC 8859-7 [29] Latin/Greek alphabet A.4
0x04 ISO/IEC 8859-8 [30] Latin/Hebrew alphabet A.5
0x05 ISO/IEC 8859-9 [31] Latin alphabet No. 5 A.6
0x06 ISO/IEC 8859-10 [32] Latin alphabet No. 6 A.7
0x07 ISO/IEC 8859-11 [33] Latin/Thai (draft only) A.8
0x08 reserved for future use (see note)
0x09 ISO/IEC 8859-13 [34] Latin alphabet No. 7 A.9
0x0A ISO/IEC 8859-14 [35] Latin alphabet No. 8 (Celtic) A.10
0x0B ISO/IEC 8859-15 [36] Latin alphabet No. 9 A.11
0x0C to 0x0F reserved for future use
0x10 ISO/IEC 8859 See table A.4
0x11 ISO/IEC 10646 [16] Basic Multilingual Plane (BMP)
0x12 KSX1001-2004 [44] Korean Character Set
0x13 GB-2312-1980 Simplified Chinese Character
0x14 Big5 subset of ISO/IEC 10646 [16] Traditional Chinese
0x15 UTF-8 encoding of ISO/IEC 10646 [16] Basic Multilingual Plane (BMP)
0x16 to 0x1E reserved for future use
0x1F Described by encoding_type_id Described by 8 bit
Table A.4: Character Coding Tables for first byte 0x10
First byte value - Second byte value - Third Byte Value - Selected character code - table - Table Description
0x10 0x00 0x00 reserved for future use
0x10 0x00 0x01 ISO/IEC 8859-1 [23] West European
0x10 0x00 0x02 ISO/IEC 8859-2 [24] East European
0x10 0x00 0x03 ISO/IEC 8859-3 [25] South European
0x10 0x00 0x04 ISO/IEC 8859-4 [26] North and North-East European
0x10 0x00 0x05 ISO/IEC 8859-5 [27] Latin/Cyrillic A.2
0x10 0x00 0x06 ISO/IEC 8859-6 [28] Latin/Arabic A.3
0x10 0x00 0x07 ISO/IEC 8859-7 [29] Latin/Greek A.4
0x10 0x00 0x08 ISO/IEC 8859-8 [30] Latin/Hebrew A.5
0x10 0x00 0x09 ISO/IEC 8859-9 [31] West European & Turkish A.6
0x10 0x00 0x0A ISO/IEC 8859-10 [32] North European A.7
0x10 0x00 0x0B ISO/IEC 8859-11 [33] Thai A.8
0x10 0x00 0x0C Reserved for future use
0x10 0x00 0x0D ISO/IEC 8859-13 [34] Baltic A.9
0x10 0x00 0x0E ISO/IEC 8859-14 [35] Celtic A.10
0x10 0x00 0x0F ISO/IEC 8859-15 [36] West European A.11
*/
#endregion
public class DvbStringDecoder
{
static readonly string[] codePages1 =
{
null, "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "iso-8859-10", "iso-8859-11",
null, "iso-8859-13", "iso-8859-14", "iso-8859-15", null, null, null, null,
null, // codePages2 prefix
"utf-16", "x-cp20949", "x-cp20936", "utf-16", "utf-8", null, null, null,
"utf-8", null, null, null, "utf-8"
};
static readonly string[] codePages2 =
{
null, "iso-8859-1", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7",
"iso-8859-8", "iso-8859-9", "iso-8859-10", "iso-8859-11", null, "iso-8859-13", "iso-8859-14", "iso-8859-15"
};
private readonly Dictionary<string, Decoder> decoderCache = new Dictionary<string, Decoder>();
public DvbStringDecoder(Encoding defaultEncoding)
{
this.DefaultEncoding = defaultEncoding;
}
public Encoding DefaultEncoding { get; set; }
#region GetChannelNames()
public void GetChannelNames(byte[] name, int off, int len, out string longName, out string shortName)
{
longName = "";
shortName = "";
if (len == 0)
return;
byte b = name[off];
if (b == 0)
return;
Decoder decoder = this.DefaultEncoding.GetDecoder();
bool singleByteChar = true;
if (b < 0x20)
{
if (b == 0x10) // prefix for 2-byte code page
{
int cpIndex = name[off + 1] * 256 + name[off + 2];
off += 2;
len -= 2;
SetDecoder(codePages2, cpIndex, ref decoder);
}
if (b <= 0x1F)
SetDecoder(codePages1, b, ref decoder);
singleByteChar = b < 0x10;
++off;
--len;
}
if (!singleByteChar)
{
char[] buffer = new char[100];
int l= decoder.GetChars(name, off, len, buffer, 0, false);
longName = new string(buffer, 0, l);
return;
}
StringBuilder sbLong = new StringBuilder();
StringBuilder sbShort = new StringBuilder();
bool inShortMode = false;
for (int c = 0; c < len; c++)
{
int i = off + c;
b = name[i];
if (b == 0x00)
break;
char ch = '\0';
switch (b)
{
case 0x86: inShortMode = true; continue;
case 0x87: inShortMode = false; continue;
case 0x8a: ch = '\n'; break;
default:
if (b >= 0x80 && b <= 0x9f) // DVB-S control characters
continue;
break;
}
if (ch == '\0')
{
// read as many bytes as necessary to get a character
char[] charArray = new char[1];
for (int byteCnt = 1; decoder.GetChars(name, i, byteCnt, charArray, 0) == 0; byteCnt++)
++i;
ch = charArray[0];
}
if (ch == '\0')
continue;
sbLong.Append(ch);
if (inShortMode)
sbShort.Append(ch);
}
longName = sbLong.ToString();
shortName = sbShort.ToString();
}
#endregion
#region SetDecoder()
private void SetDecoder(string[] codePages, int cpIndex, ref Decoder defaultDecoder)
{
if (cpIndex >= codePages.Length)
return;
Decoder decoder;
string cp = codePages[cpIndex];
if (cp == null)
return;
if (this.decoderCache.TryGetValue(cp, out decoder))
{
defaultDecoder = decoder;
return;
}
try
{
var encoding = Encoding.GetEncoding(cp);
defaultDecoder = encoding.GetDecoder();
}
catch (ArgumentException)
{
}
decoderCache[cp] = defaultDecoder;
}
#endregion
#region GetCodepageBytes()
public static byte[] GetCodepageBytes(Encoding encoding)
{
var encName = encoding.WebName;
for (int i = 0; i < codePages1.Length; i++)
{
if (codePages1[i] == encName)
return new [] {(byte)i};
}
for (int i = 0; i < codePages2.Length; i++)
{
if (codePages2[i] == encName)
return new[] { (byte)0x10, (byte)i };
}
return new byte[0];
}
#endregion
#region GetEncoding()
/// <summary>
/// Pass in either a value &lt;=0x1F excluding 0x10 or 0x10xxyy
/// </summary>
public static Encoding GetEncoding(int encodingMarker)
{
string enc = null;
if (encodingMarker < 0x20)
enc = codePages1[encodingMarker];
else
{
encodingMarker &= 0xFFFF;
if (encodingMarker < codePages2.Length)
enc = codePages2[encodingMarker];
}
return enc == null ? null : Encoding.GetEncoding(enc);
}
#endregion
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.IO;
namespace ChanSort.Api
{
public class IniFile
{
#region class Section
public class Section
{
private readonly Dictionary<string, string> data = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
public Section(string name)
{
this.Name = name;
}
#region Name
public string Name { get; private set; }
#endregion
#region Set()
internal void Set(string key, string value)
{
data[key] = value;
}
#endregion
#region Keys
public IEnumerable<string> Keys { get { return data.Keys; } }
#endregion
#region GetString()
public string GetString(string key)
{
string value;
if (!data.TryGetValue(key, out value))
return null;
return value;
}
#endregion
#region GetInt()
public int GetInt(string key, int defaultValue = 0)
{
string value;
if (!data.TryGetValue(key, out value))
return defaultValue;
return this.ParseNumber(value);
}
#endregion
#region GetBytes()
public byte[] GetBytes(string key)
{
string value;
if (!data.TryGetValue(key, out value))
return null;
if (string.IsNullOrEmpty(value))
return new byte[0];
string[] parts = value.Split(',');
byte[] bytes = new byte[parts.Length];
int i = 0;
foreach (var part in parts)
bytes[i++] = (byte)this.ParseNumber(part);
return bytes;
}
#endregion
#region GetIntList()
public int[] GetIntList(string key)
{
string value = this.GetString(key);
if (string.IsNullOrEmpty(value))
return new int[0];
string[] numbers = value.Split(',');
int[] ret = new int[numbers.Length];
for (int i = 0; i < numbers.Length; i++)
ret[i] = this.ParseNumber(numbers[i]);
return ret;
}
#endregion
#region ParseNumber()
private int ParseNumber(string value)
{
if (value.ToLower().StartsWith("0x"))
{
try { return Convert.ToInt32(value, 16); }
catch { return 0; }
}
int intValue;
int.TryParse(value, out intValue);
return intValue;
}
#endregion
}
#endregion
private readonly Dictionary<string, Section> sectionDict;
private readonly List<Section> sectionList;
public IniFile(string fileName)
{
this.sectionDict = new Dictionary<string, Section>();
this.sectionList = new List<Section>();
this.ReadIniFile(fileName);
}
public IEnumerable<Section> Sections
{
get { return this.sectionList; }
}
public Section GetSection(string sectionName)
{
return sectionDict.TryGet(sectionName);
}
#region ReadIniFile()
private void ReadIniFile(string fileName)
{
using (StreamReader rdr = new StreamReader(fileName))
{
Section currentSection = null;
string line;
string key = null;
string val = null;
while ((line = rdr.ReadLine()) != null)
{
string trimmedLine = line.Trim();
if (trimmedLine.StartsWith(";"))
continue;
if (trimmedLine.StartsWith("["))
{
string sectionName = trimmedLine.EndsWith("]")
? trimmedLine.Substring(1, trimmedLine.Length - 2)
: trimmedLine.Substring(1);
currentSection = new Section(sectionName);
this.sectionList.Add(currentSection);
this.sectionDict[sectionName] = currentSection;
continue;
}
if (currentSection == null)
continue;
if (val == null)
{
int idx = trimmedLine.IndexOf("=");
if (idx < 0)
continue;
key = trimmedLine.Substring(0, idx).Trim();
val = trimmedLine.Substring(idx + 1).Trim();
}
else
val += line;
if (val.EndsWith("\\"))
val = val.Substring(val.Length - 1).Trim();
else
{
currentSection.Set(key, val);
val = null;
}
}
}
}
#endregion
}
}

View File

@@ -0,0 +1,47 @@
using System.Collections.Generic;
using System.IO;
namespace ChanSort.Api
{
public class MappingPool<T> where T : DataMapping
{
private const string ERR_unknownACTChannelDataLength = "Configuration doesn't contain a {0} data mapping for length {1}";
private readonly Dictionary<string, T> mappings = new Dictionary<string, T>();
private readonly string caption;
public System.Text.Encoding DefaultEncoding { get; set; }
public MappingPool(string caption)
{
this.caption = caption;
}
public void AddMapping(int dataLength, T mapping)
{
this.AddMapping(dataLength.ToString(), mapping);
}
public void AddMapping(string id, T mapping)
{
this.mappings.Add(id, mapping);
}
public T GetMapping(int dataLength, bool throwException = true)
{
return this.GetMapping(dataLength.ToString(), throwException);
}
public T GetMapping(string id, bool throwException = true)
{
if (id == "0" || string.IsNullOrEmpty(id))
return null;
T mapping;
if (!mappings.TryGetValue(id, out mapping) && throwException)
throw new FileLoadException(string.Format(ERR_unknownACTChannelDataLength, this.caption, id));
if (mapping != null && this.DefaultEncoding != null)
mapping.DefaultEncoding = this.DefaultEncoding;
return mapping;
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using System.Collections.Generic;
namespace ChanSort.Api
{
public static class Tools
{
public static V TryGet<K, V>(this IDictionary<K, V> dict, K key)
{
V val;
dict.TryGetValue(key, out val);
return val;
}
#region GetAnalogChannelNumber()
public static string GetAnalogChannelNumber(int freq)
{
if (freq < 41) return "";
if (freq <= 68) return ((freq - 41)/7 + 1).ToString("d2"); // Band I (01-04)
if (freq < 105) return "";
if (freq <= 174) return "S" + ((freq - 105)/7 + 1).ToString("d2"); // Midband (S01-S10)
if (freq <= 230) return ((freq - 175)/7 + 5).ToString("d2"); // Band III (05-12)
if (freq <= 300) return "S" + ((freq - 231)/7 + 11); // Superband (S11-S20)
if (freq <= 469) return "S" + ((freq - 303)/8 + 21); // Hyperband (S21-S41)
if (freq <= 1000) return ((freq - 471)/8 + 21).ToString("d2"); // Band IV, V
return "";
}
#endregion
#region GetInt16/32()
public static int GetInt16(byte[] data, int offset, bool littleEndian)
{
return littleEndian ? BitConverter.ToInt16(data, offset) : (data[offset] << 8) + data[offset + 1];
}
public static int GetInt32(byte[] data, int offset, bool littleEndian)
{
return littleEndian ? BitConverter.ToInt32(data, offset) :
(data[offset] << 24) + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3];
}
#endregion
#region SetInt16/32()
public static void SetInt16(byte[] data, int offset, int value, bool littleEndian = true)
{
if (littleEndian)
{
data[offset + 0] = (byte) value;
data[offset + 1] = (byte) (value >> 8);
}
else
{
data[offset + 0] = (byte)(value >> 8);
data[offset + 1] = (byte) value;
}
}
public static void SetInt32(byte[] data, int offset, int value, bool littleEndian = true)
{
if (littleEndian)
{
data[offset + 0] = (byte) value;
data[offset + 1] = (byte) (value >> 8);
data[offset + 2] = (byte) (value >> 16);
data[offset + 3] = (byte) (value >> 24);
}
else
{
data[offset + 0] = (byte)(value >> 24);
data[offset + 1] = (byte)(value >> 16);
data[offset + 2] = (byte)(value >> 8);
data[offset + 3] = (byte)value;
}
}
#endregion
#region MemCopy(), MemSet()
public static void MemCopy(byte[] source, int sourceIndex, byte[] dest, int destIndex, int count)
{
for (int i = 0; i < count; i++)
dest[destIndex + i] = source[sourceIndex + i];
}
public static void MemSet(byte[] data, int offset, byte value, int count)
{
for (int i = 0; i < count; i++)
data[offset++] = value;
}
#endregion
#region ReverseByteOrder()
public static ushort ReverseByteOrder(ushort input)
{
return (ushort)(((input & 0x00FF) << 8) | (input >> 8));
}
public static uint ReverseByteOrder(uint input)
{
return ((input & 0x000000FF) << 24) | ((input & 0x0000FF00) << 8) | ((input & 0x00FF0000) >> 8) | ((input & 0xFF000000) >> 24);
}
#endregion
#region HexDecode()
public static byte[] HexDecode(string input)
{
var bytes = new byte[input.Length/2];
for (int i = 0, c = input.Length/2; i < c; i++)
{
char ch = Char.ToUpper(input[i*2]);
var high = Char.IsDigit(ch) ? ch - '0' : ch - 'A' + 10;
ch = Char.ToUpper(input[i*2 + 1]);
var low = Char.IsDigit(ch) ? ch - '0' : ch - 'A' + 10;
bytes[i] = (byte)((high << 4) | low);
}
return bytes;
}
#endregion
}
}