Remove tabs and trailing whitespace

This commit is contained in:
hawken 2019-01-07 23:24:34 +00:00
parent 4ab82f7436
commit ba1794f64b
61 changed files with 1576 additions and 1820 deletions

View file

@ -15,14 +15,14 @@ namespace Emby.Server.Implementations.Archiving
/// </summary>
public class ZipClient : IZipClient
{
private readonly IFileSystem _fileSystem;
private readonly IFileSystem _fileSystem;
public ZipClient(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
public ZipClient(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}
/// <summary>
/// <summary>
/// Extracts all.
/// </summary>
/// <param name="sourceFile">The source file.</param>
@ -30,7 +30,7 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = _fileSystem.OpenRead(sourceFile))
using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAll(fileStream, targetPath, overwriteExistingFiles);
}
@ -116,7 +116,7 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = _fileSystem.OpenRead(sourceFile))
using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles);
}
@ -156,7 +156,7 @@ namespace Emby.Server.Implementations.Archiving
/// <param name="overwriteExistingFiles">if set to <c>true</c> [overwrite existing files].</param>
public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles)
{
using (var fileStream = _fileSystem.OpenRead(sourceFile))
using (var fileStream = _fileSystem.OpenRead(sourceFile))
{
ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles);
}

View file

@ -10,8 +10,8 @@ namespace Emby.Server.Implementations.Devices
public class DeviceId
{
private readonly IApplicationPaths _appPaths;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly object _syncLock = new object();
@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Devices
{
lock (_syncLock)
{
var value = File.ReadAllText(CachePath, Encoding.UTF8);
var value = File.ReadAllText(CachePath, Encoding.UTF8);
Guid guid;
if (Guid.TryParse(value, out guid))
@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Devices
{
var path = CachePath;
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
lock (_syncLock)
{
@ -92,13 +92,13 @@ namespace Emby.Server.Implementations.Devices
public DeviceId(IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem)
{
if (fileSystem == null) {
throw new ArgumentNullException ("fileSystem");
}
if (fileSystem == null) {
throw new ArgumentNullException ("fileSystem");
}
_appPaths = appPaths;
_logger = logger;
_fileSystem = fileSystem;
_fileSystem = fileSystem;
}
public string Value

View file

@ -10,11 +10,11 @@ namespace Emby.Server.Implementations.Net
{
public class SocketFactory : ISocketFactory
{
// THIS IS A LINKED FILE - SHARED AMONGST MULTIPLE PLATFORMS
// THIS IS A LINKED FILE - SHARED AMONGST MULTIPLE PLATFORMS
// Be careful to check any changes compile and work for all platform projects it is shared in.
// Not entirely happy with this. Would have liked to have done something more generic/reusable,
// but that wasn't really the point so kept to YAGNI principal for now, even if the
// but that wasn't really the point so kept to YAGNI principal for now, even if the
// interfaces are a bit ugly, specific and make assumptions.
private readonly ILogger _logger;

View file

@ -8,7 +8,7 @@ using MediaBrowser.Model.Net;
namespace Emby.Server.Implementations.Net
{
// THIS IS A LINKED FILE - SHARED AMONGST MULTIPLE PLATFORMS
// THIS IS A LINKED FILE - SHARED AMONGST MULTIPLE PLATFORMS
// Be careful to check any changes compile and work for all platform projects it is shared in.
public sealed class UdpSocket : DisposableManagedObjectBase, ISocket

View file

@ -7,7 +7,7 @@ using System.Text.RegularExpressions;
namespace System.Net
{
/// <summary>
/// IP Network utility class.
/// IP Network utility class.
/// Use IPNetwork.Parse to create instances.
/// </summary>
public class IPNetwork : IComparable<IPNetwork>
@ -210,7 +210,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100 - 255.255.255.0
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -231,7 +231,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100/24
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -253,7 +253,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100 255.255.255.0
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -276,7 +276,7 @@ namespace System.Net
/// <summary>
/// 192.168.0.1/24
/// 192.168.0.1 255.255.255.0
///
///
/// Network : 192.168.0.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -303,7 +303,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100 - 255.255.255.0
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -329,7 +329,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100/24
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -354,7 +354,7 @@ namespace System.Net
/// <summary>
/// 192.168.0.1/24
/// 192.168.0.1 255.255.255.0
///
///
/// Network : 192.168.0.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -379,7 +379,7 @@ namespace System.Net
/// <summary>
/// 192.168.0.1/24
/// 192.168.0.1 255.255.255.0
///
///
/// Network : 192.168.0.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -409,7 +409,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100 - 255.255.255.0
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -520,7 +520,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100 255.255.255.0
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -578,7 +578,7 @@ namespace System.Net
/// <summary>
/// 192.168.168.100/24
///
///
/// Network : 192.168.168.0
/// Netmask : 255.255.255.0
/// Cidr : 24
@ -962,7 +962,7 @@ namespace System.Net
/// 20180217 lduchosal
/// impossible to reach code, byte cannot be negative :
///
///
/// if (cidr < 0) {
/// if (tryParse == false) {
/// throw new ArgumentOutOfRangeException("cidr");
@ -1275,7 +1275,7 @@ namespace System.Net
}
/// <summary>
/// return true if ipaddress is contained in
/// return true if ipaddress is contained in
/// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1
/// </summary>
/// <param name="ipaddress"></param>
@ -1294,7 +1294,7 @@ namespace System.Net
}
/// <summary>
/// return true if ipnetwork is contained in
/// return true if ipnetwork is contained in
/// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1
/// </summary>
/// <returns></returns>
@ -1395,9 +1395,9 @@ namespace System.Net
/// <summary>
/// Supernet two consecutive cidr equal subnet into a single one
/// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
/// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
/// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
/// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24
/// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24
/// </summary>
/// <param name="network2"></param>
/// <returns></returns>
@ -1410,9 +1410,9 @@ namespace System.Net
/// <summary>
/// Try to supernet two consecutive cidr equal subnet into a single one
/// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
/// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
/// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
/// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24
/// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24
/// </summary>
/// <param name="network2"></param>
/// <returns></returns>
@ -1841,13 +1841,13 @@ namespace System.Net
#region TryGuessCidr
/// <summary>
///
/// Class Leading bits Default netmask
/// A (CIDR /8) 00 255.0.0.0
/// A (CIDR /8) 01 255.0.0.0
/// B (CIDR /16) 10 255.255.0.0
/// C (CIDR /24) 11 255.255.255.0
///
///
/// Class Leading bits Default netmask
/// A (CIDR /8) 00 255.0.0.0
/// A (CIDR /8) 01 255.0.0.0
/// B (CIDR /16) 10 255.255.0.0
/// C (CIDR /24) 11 255.255.255.0
///
/// </summary>
/// <param name="ip"></param>
/// <param name="cidr"></param>
@ -1931,7 +1931,7 @@ namespace System.Net
/**
* Need a better way to do it
*
*
#region TrySubstractNetwork
public static bool TrySubstractNetwork(IPNetwork[] ipnetworks, IPNetwork substract, out IEnumerable<IPNetwork> result) {

View file

@ -38,12 +38,11 @@
namespace UniversalDetector.Core
{
/// <summary>
/// Base class for the Character Distribution Method, used for
/// Base class for the Character Distribution Method, used for
/// the CJK encodings
/// </summary>
public abstract class CharDistributionAnalyser
{
protected const float SURE_YES = 0.99f;
protected const float SURE_NO = 0.01f;
protected const int MINIMUM_DATA_THRESHOLD = 4;
@ -57,19 +56,19 @@ namespace UniversalDetector.Core
//Total character encounted.
protected int totalChars;
// Mapping table to get frequency order from char order (get from GetOrder())
protected int[] charToFreqOrder;
// Size of above table
protected int tableSize;
//This is a constant value varies from language to language, it is used
// in calculating confidence.
protected float typicalDistributionRatio;
//This is a constant value varies from language to language, it is used
// in calculating confidence.
protected float typicalDistributionRatio;
public CharDistributionAnalyser()
{
{
Reset();
}
@ -77,10 +76,10 @@ namespace UniversalDetector.Core
/// Feed a block of data and do distribution analysis
/// </summary>
/// </param>
//public abstract void HandleData(byte[] buf, int offset, int len);
//public abstract void HandleData(byte[] buf, int offset, int len);
/// <summary>
/// we do not handle character base on its original encoding string, but
/// we do not handle character base on its original encoding string, but
/// convert this encoding string to a number, here called order.
/// This allow multiple encoding of a language to share one frequency table
/// </summary>
@ -88,9 +87,9 @@ namespace UniversalDetector.Core
/// <param name="offset"></param>
/// <returns></returns>
public abstract int GetOrder(byte[] buf, int offset);
/// <summary>
/// Feed a character with known length
/// Feed a character with known length
/// </summary>
/// <param name="buf">A <see cref="System.Byte"/></param>
/// <param name="offset">buf offset</param>
@ -107,13 +106,13 @@ namespace UniversalDetector.Core
}
}
public virtual void Reset()
public virtual void Reset()
{
done = false;
totalChars = 0;
freqChars = 0;
}
/// <summary>
/// return confidence base on received data
/// </summary>
@ -133,16 +132,16 @@ namespace UniversalDetector.Core
//normalize confidence, (we don't want to be 100% sure)
return SURE_YES;
}
//It is not necessary to receive all data to draw conclusion. For charset detection,
// certain amount of data is enough
public bool GotEnoughData()
public bool GotEnoughData()
{
return totalChars > ENOUGH_DATA_THRESHOLD;
}
}
public class GB18030DistributionAnalyser : CharDistributionAnalyser
{
// GB2312 most frequently used character table
@ -155,7 +154,7 @@ namespace UniversalDetector.Core
*
* Idea Distribution Ratio = 0.79135/(1-0.79135) = 3.79
* Random Distribution Ration = 512 / (3755 - 512) = 0.157
*
*
* Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR
*****************************************************************************/
@ -400,8 +399,8 @@ namespace UniversalDetector.Core
381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189,
852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, //last 512
/***************************************************************************************
*Everything below is of no interest for detection purpose *
/***************************************************************************************
*Everything below is of no interest for detection purpose *
***************************************************************************************
5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636,
@ -601,7 +600,7 @@ namespace UniversalDetector.Core
tableSize = GB2312_TABLE_SIZE;
typicalDistributionRatio = GB2312_TYPICAL_DISTRIBUTION_RATIO;
}
/// <summary>
/// for GB2312 encoding, we are interested
/// first byte range: 0xb0 -- 0xfe
@ -609,20 +608,20 @@ namespace UniversalDetector.Core
/// no validation needed here. State machine has done that
/// </summary>
/// <returns></returns>
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xB0 && buf[offset+1] >= 0xA1)
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xB0 && buf[offset+1] >= 0xA1)
return 94 * (buf[offset] - 0xb0) + buf[offset+1] - 0xA1;
else
return -1;
}
}
public class EUCTWDistributionAnalyser : CharDistributionAnalyser
{
// EUCTW frequency table
// Converted from big5 work
// by Taiwan's Mandarin Promotion Council
// Converted from big5 work
// by Taiwan's Mandarin Promotion Council
// <http://www.edu.tw:81/mandr/>
/******************************************************************************
* 128 --> 0.42261
@ -633,7 +632,7 @@ namespace UniversalDetector.Core
*
* Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98
* Random Distribution Ration = 512/(5401-512)=0.105
*
*
* Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR
*****************************************************************************/
@ -979,8 +978,8 @@ namespace UniversalDetector.Core
890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, // 8086
2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, // 8102
/***************************************************************************************
*Everything below is of no interest for detection purpose *
/***************************************************************************************
*Everything below is of no interest for detection purpose *
***************************************************************************************
2515,1613,4582,8119,3312,3866,2516,8120,4058,8121,1637,4059,2466,4583,3867,8122, // 8118
@ -1022,7 +1021,7 @@ namespace UniversalDetector.Core
8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693, // 8694
8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,8708,8709, // 8710
8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,8723,8724,8725, // 8726
8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973
8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973
****************************************************************************************/
};
@ -1038,15 +1037,15 @@ namespace UniversalDetector.Core
/// second byte range: 0xa1 -- 0xfe
/// no validation needed here. State machine has done that
/// </summary>
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xC4)
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xC4)
return 94 * (buf[offset] - 0xC4) + buf[offset+1] - 0xA1;
else
return -1;
}
}
public class EUCKRDistributionAnalyser : CharDistributionAnalyser
{
// Sampling from about 20M text materials include literature and computer technology
@ -1215,8 +1214,8 @@ namespace UniversalDetector.Core
2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042,
670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, //512, 256
/***************************************************************************************
* Everything below is of no interest for detection purpose
/***************************************************************************************
* Everything below is of no interest for detection purpose *
***************************************************************************************
2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,
@ -1619,32 +1618,32 @@ namespace UniversalDetector.Core
8704,8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,
8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,
8736,8737,8738,8739,8740,8741 */ };
public EUCKRDistributionAnalyser()
{
charToFreqOrder = EUCKR_CHAR2FREQ_ORDER;
tableSize = EUCKR_TABLE_SIZE;
typicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO;
typicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO;
}
/// <summary>
/// first byte range: 0xb0 -- 0xfe
/// second byte range: 0xa1 -- 0xfe
/// no validation needed here. State machine has done that
/// </summary>
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xB0)
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xB0)
return 94 * (buf[offset] - 0xB0) + buf[offset+1] - 0xA1;
else
return -1;
}
}
public class BIG5DistributionAnalyser : CharDistributionAnalyser
{
// Big5 frequency table
// by Taiwan's Mandarin Promotion Council
// by Taiwan's Mandarin Promotion Council
// <http://www.edu.tw:81/mandr/>
/******************************************************************************
* 128 --> 0.42261
@ -1655,7 +1654,7 @@ namespace UniversalDetector.Core
*
* Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98
* Random Distribution Ration = 512/(5401-512)=0.105
*
*
* Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR
*****************************************************************************/
@ -2001,8 +2000,8 @@ namespace UniversalDetector.Core
890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, // 5360
2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, // 5376 //last 512
/***************************************************************************************
*Everything below is of no interest for detection purpose *
/***************************************************************************************
*Everything below is of no interest for detection purpose *
***************************************************************************************
2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, // 5392
@ -2545,29 +2544,29 @@ namespace UniversalDetector.Core
13968,13969,13970,13971,13972, //13973
****************************************************************************************/
};
public BIG5DistributionAnalyser()
{
charToFreqOrder = BIG5_CHAR2FREQ_ORDER;
tableSize = BIG5_TABLE_SIZE;
typicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO;
typicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO;
}
/// <summary>
/// first byte range: 0xa4 -- 0xfe
/// second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe
/// no validation needed here. State machine has done that
/// </summary>
public override int GetOrder(byte[] buf, int offset)
{
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xA4) {
if (buf[offset+1] >= 0xA1)
return 157 * (buf[offset] - 0xA4) + buf[offset+1] - 0xA1 + 63;
else
return 157 * (buf[offset] - 0xA4) + buf[offset+1] - 0x40;
} else {
return -1;
}
return -1;
}
}
}
@ -2575,7 +2574,7 @@ namespace UniversalDetector.Core
{
//Sampling from about 20M text materials include literature and computer technology
// Japanese frequency table, applied to both S-JIS and EUC-JP
//They are sorted in order.
//They are sorted in order.
/******************************************************************************
* 128 --> 0.77094
@ -2586,8 +2585,8 @@ namespace UniversalDetector.Core
*
* Idea Distribution Ratio = 0.92635 / (1-0.92635) = 12.58
* Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191
*
* Typical Distribution Ratio, 25% of IDR
*
* Typical Distribution Ratio, 25% of IDR
*****************************************************************************/
protected static float SJIS_TYPICAL_DISTRIBUTION_RATIO = 3.0f;
@ -2869,8 +2868,8 @@ namespace UniversalDetector.Core
1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, // 4352
2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, // 4368 //last 512
/***************************************************************************************
*Everything below is of no interest for detection purpose *
/***************************************************************************************
*Everything below is of no interest for detection purpose *
***************************************************************************************
2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, // 4384
@ -3118,31 +3117,31 @@ namespace UniversalDetector.Core
8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, // 8256
8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, // 8272
****************************************************************************************/
};
};
public SJISDistributionAnalyser()
{
charToFreqOrder = SJIS_CHAR2FREQ_ORDER;
tableSize = SJIS_TABLE_SIZE;
typicalDistributionRatio = SJIS_TYPICAL_DISTRIBUTION_RATIO;
typicalDistributionRatio = SJIS_TYPICAL_DISTRIBUTION_RATIO;
}
/// <summary>
/// first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe
/// second byte range: 0x40 -- 0x7e, 0x81 -- oxfe
/// no validation needed here. State machine has done that
/// </summary>
public override int GetOrder(byte[] buf, int offset)
{
public override int GetOrder(byte[] buf, int offset)
{
int order = 0;
if (buf[offset] >= 0x81 && buf[offset] <= 0x9F)
if (buf[offset] >= 0x81 && buf[offset] <= 0x9F)
order = 188 * (buf[offset] - 0x81);
else if (buf[offset] >= 0xE0 && buf[offset] <= 0xEF)
else if (buf[offset] >= 0xE0 && buf[offset] <= 0xEF)
order = 188 * (buf[offset] - 0xE0 + 31);
else
return -1;
order += buf[offset+1] - 0x40;
if (buf[offset+1] > 0x7F)
order--;
return order;
@ -3154,20 +3153,18 @@ namespace UniversalDetector.Core
public EUCJPDistributionAnalyser() : base()
{
}
/// <summary>
/// first byte range: 0xa0 -- 0xfe
/// second byte range: 0xa1 -- 0xfe
/// no validation needed here. State machine has done that
/// </summary>
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xA0)
public override int GetOrder(byte[] buf, int offset)
{
if (buf[offset] >= 0xA0)
return 94 * (buf[offset] - 0xA1) + buf[offset+1] - 0xA1;
else
return -1;
}
}
}

View file

@ -12,23 +12,22 @@ namespace Emby.XmlTv.Test
[TestClass]
public class XmlTvReaderLanguageTests
{
/*
<title lang="es">Homes Under the Hammer - Spanish</title>
<title lang="es">Homes Under the Hammer - Spanish 2</title>
<title lang="en">Homes Under the Hammer - English</title>
<title lang="en">Homes Under the Hammer - English 2</title>
<title lang="">Homes Under the Hammer - Empty Language</title>
<title lang="">Homes Under the Hammer - Empty Language 2</title>
<title>Homes Under the Hammer - No Language</title>
<title>Homes Under the Hammer - No Language 2</title>
*/
/* <title lang="es">Homes Under the Hammer - Spanish</title>
* <title lang="es">Homes Under the Hammer - Spanish 2</title>
* <title lang="en">Homes Under the Hammer - English</title>
* <title lang="en">Homes Under the Hammer - English 2</title>
* <title lang="">Homes Under the Hammer - Empty Language</title>
* <title lang="">Homes Under the Hammer - Empty Language 2</title>
* <title>Homes Under the Hammer - No Language</title>
* <title>Homes Under the Hammer - No Language 2</title>
*/
/* Expected Behaviour:
- Language = Null Homes Under the Hammer - No Language
- Language = "" Homes Under the Hammer - No Language
- Language = es Homes Under the Hammer - Spanish
- Language = en Homes Under the Hammer - English
*/
/* Expected Behaviour:
* - Language = Null Homes Under the Hammer - No Language
* - Language = "" Homes Under the Hammer - No Language
* - Language = es Homes Under the Hammer - Spanish
* - Language = en Homes Under the Hammer - English
*/
[TestMethod]
[DeploymentItem("Xml Files\\MultilanguageData.xml")]

View file

@ -580,7 +580,7 @@ namespace Emby.XmlTv.Classes
public void ParseEpisodeDataForOnScreen(XmlReader reader, XmlTvProgram result)
{
//// example: 'Episode #FFEE'
//// example: 'Episode #FFEE'
//serEpNum = ConvertHTMLToAnsi(nodeEpisodeNum);
//int num1 = serEpNum.IndexOf("#", 0);
//if (num1 < 0) num1 = 0;
@ -832,23 +832,22 @@ namespace Emby.XmlTv.Classes
public void ProcessNode(XmlReader reader, Action<string> setter, string languageRequired = null, Action<string> allOccurrencesSetter = null)
{
/*
<title lang="es">Homes Under the Hammer - Spanish</title>
<title lang="es">Homes Under the Hammer - Spanish 2</title>
<title lang="en">Homes Under the Hammer - English</title>
<title lang="en">Homes Under the Hammer - English 2</title>
<title lang="">Homes Under the Hammer - Empty Language</title>
<title lang="">Homes Under the Hammer - Empty Language 2</title>
<title>Homes Under the Hammer - No Language</title>
<title>Homes Under the Hammer - No Language 2</title>
*/
/* <title lang="es">Homes Under the Hammer - Spanish</title>
* <title lang="es">Homes Under the Hammer - Spanish 2</title>
* <title lang="en">Homes Under the Hammer - English</title>
* <title lang="en">Homes Under the Hammer - English 2</title>
* <title lang="">Homes Under the Hammer - Empty Language</title>
* <title lang="">Homes Under the Hammer - Empty Language 2</title>
* <title>Homes Under the Hammer - No Language</title>
* <title>Homes Under the Hammer - No Language 2</title>
*/
/* Expected Behaviour:
- Language = Null Homes Under the Hammer - No Language
- Language = "" Homes Under the Hammer - No Language
- Language = es Homes Under the Hammer - Spanish
- Language = en Homes Under the Hammer - English
*/
/* Expected Behaviour:
* - Language = Null Homes Under the Hammer - No Language
* - Language = "" Homes Under the Hammer - No Language
* - Language = es Homes Under the Hammer - Spanish
* - Language = en Homes Under the Hammer - English
*/
var results = new List<Tuple<string, string>>();
@ -921,23 +920,22 @@ namespace Emby.XmlTv.Classes
public void ProcessMultipleNodes(XmlReader reader, Action<string> setter, string languageRequired = null)
{
/*
<category lang="en">Property - English</category>
<category lang="en">Property - English 2</category>
<category lang="es">Property - Spanish</category>
<category lang="es">Property - Spanish 2</category>
<category lang="">Property - Empty Language</category>
<category lang="">Property - Empty Language 2</category>
<category>Property - No Language</category>
<category>Property - No Language 2</category>
*/
/* <category lang="en">Property - English</category>
* <category lang="en">Property - English 2</category>
* <category lang="es">Property - Spanish</category>
* <category lang="es">Property - Spanish 2</category>
* <category lang="">Property - Empty Language</category>
* <category lang="">Property - Empty Language 2</category>
* <category>Property - No Language</category>
* <category>Property - No Language 2</category>
*/
/* Expected Behaviour:
- Language = Null Property - No Language / Property - No Language 2
- Language = "" Property - Empty Language / Property - Empty Language 2
- Language = es Property - Spanish / Property - Spanish 2
- Language = en Property - English / Property - English 2
*/
/* Expected Behaviour:
* - Language = Null Property - No Language / Property - No Language 2
* - Language = "" Property - Empty Language / Property - Empty Language 2
* - Language = es Property - Spanish / Property - Spanish 2
* - Language = en Property - English / Property - English 2
*/
var currentElementName = reader.Name;
var values = new[] { new { Language = reader.GetAttribute("lang"), Value = reader.ReadElementContentAsString() } }.ToList();

View file

@ -97,12 +97,12 @@ namespace Jellyfin.SocketSharp
}
#if NET_4_0
if (validateRequestNewMode && !checked_form) {
// Setting this before calling the validator prevents
// possible endless recursion
checked_form = true;
ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form);
} else
if (validateRequestNewMode && !checked_form) {
// Setting this before calling the validator prevents
// possible endless recursion
checked_form = true;
ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form);
} else
#endif
if (validate_form && !checked_form)
{
@ -546,7 +546,7 @@ namespace Jellyfin.SocketSharp
const byte HYPHEN = (byte)'-', LF = (byte)'\n', CR = (byte)'\r';
// See RFC 2046
// See RFC 2046
// In the case of multipart entities, in which one or more different
// sets of data are combined in a single body, a "multipart" media type
// field must appear in the entity's header. The body must then contain

View file

@ -133,7 +133,7 @@ namespace MediaBrowser.Api.Images
{
try
{
return _fileSystem.GetFiles(path, BaseItem.SupportedImageExtensions, false, true)
return _fileSystem.GetFiles(path, BaseItem.SupportedImageExtensions, false, true)
.Select(i => new ImageByNameInfo
{
Name = _fileSystem.GetFileNameWithoutExtension(i),
@ -185,7 +185,7 @@ namespace MediaBrowser.Api.Images
var paths = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(_appPaths.GeneralPath, request.Name, filename + i)).ToList();
var path = paths.FirstOrDefault(_fileSystem.FileExists) ?? paths.FirstOrDefault();
var path = paths.FirstOrDefault(_fileSystem.FileExists) ?? paths.FirstOrDefault();
return _resultFactory.GetStaticFileResult(Request, path);
}
@ -199,11 +199,11 @@ namespace MediaBrowser.Api.Images
{
var themeFolder = Path.Combine(_appPaths.RatingsPath, request.Theme);
if (_fileSystem.DirectoryExists(themeFolder))
if (_fileSystem.DirectoryExists(themeFolder))
{
var path = BaseItem.SupportedImageExtensions
.Select(i => Path.Combine(themeFolder, request.Name + i))
.FirstOrDefault(_fileSystem.FileExists);
.FirstOrDefault(_fileSystem.FileExists);
if (!string.IsNullOrEmpty(path))
{
@ -213,14 +213,14 @@ namespace MediaBrowser.Api.Images
var allFolder = Path.Combine(_appPaths.RatingsPath, "all");
if (_fileSystem.DirectoryExists(allFolder))
if (_fileSystem.DirectoryExists(allFolder))
{
// Avoid implicitly captured closure
var currentRequest = request;
var path = BaseItem.SupportedImageExtensions
.Select(i => Path.Combine(allFolder, currentRequest.Name + i))
.FirstOrDefault(_fileSystem.FileExists);
.FirstOrDefault(_fileSystem.FileExists);
if (!string.IsNullOrEmpty(path))
{
@ -240,10 +240,10 @@ namespace MediaBrowser.Api.Images
{
var themeFolder = Path.Combine(_appPaths.MediaInfoImagesPath, request.Theme);
if (_fileSystem.DirectoryExists(themeFolder))
if (_fileSystem.DirectoryExists(themeFolder))
{
var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(themeFolder, request.Name + i))
.FirstOrDefault(_fileSystem.FileExists);
.FirstOrDefault(_fileSystem.FileExists);
if (!string.IsNullOrEmpty(path))
{
@ -253,13 +253,13 @@ namespace MediaBrowser.Api.Images
var allFolder = Path.Combine(_appPaths.MediaInfoImagesPath, "all");
if (_fileSystem.DirectoryExists(allFolder))
if (_fileSystem.DirectoryExists(allFolder))
{
// Avoid implicitly captured closure
var currentRequest = request;
var path = BaseItem.SupportedImageExtensions.Select(i => Path.Combine(allFolder, currentRequest.Name + i))
.FirstOrDefault(_fileSystem.FileExists);
.FirstOrDefault(_fileSystem.FileExists);
if (!string.IsNullOrEmpty(path))
{

View file

@ -740,7 +740,7 @@ namespace MediaBrowser.Controller.MediaEncoding
level = NormalizeTranscodingLevel(state.OutputVideoCodec, level);
// h264_qsv and h264_nvenc expect levels to be expressed as a decimal. libx264 supports decimal and non-decimal format
// also needed for libx264 due to https://trac.ffmpeg.org/ticket/3307
// also needed for libx264 due to https://trac.ffmpeg.org/ticket/3307
if (string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) ||
string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase))
{
@ -1706,7 +1706,8 @@ namespace MediaBrowser.Controller.MediaEncoding
if (string.Equals(outputVideoCodec, "libvpx", StringComparison.OrdinalIgnoreCase))
{
// per docs:
// -threads number of threads to use for encoding, can't be 0 [auto] with VP8 (recommended value : number of real cores - 1)
// -threads number of threads to use for encoding, can't be 0 [auto] with VP8
// (recommended value : number of real cores - 1)
return Math.Max(Environment.ProcessorCount - 1, 1);
}

View file

@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Net
object GetResult(IRequest requestContext, byte[] content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetResult(IRequest requestContext, Stream content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetResult(IRequest requestContext, string content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetResult(IRequest requestContext, string content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetRedirectResult(string url);
@ -43,10 +43,10 @@ namespace MediaBrowser.Controller.Net
/// <param name="responseHeaders">The response headers.</param>
/// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param>
/// <returns>System.Object.</returns>
Task<object> GetStaticResult(IRequest requestContext,
Guid cacheKey,
Task<object> GetStaticResult(IRequest requestContext,
Guid cacheKey,
DateTime? lastDateModified,
TimeSpan? cacheDuration,
TimeSpan? cacheDuration,
string contentType, Func<Task<Stream>> factoryFn,
IDictionary<string, string> responseHeaders = null,
bool isHeadRequest = false);
@ -74,7 +74,7 @@ namespace MediaBrowser.Controller.Net
/// <param name="requestContext">The request context.</param>
/// <param name="options">The options.</param>
/// <returns>System.Object.</returns>
Task<object> GetStaticFileResult(IRequest requestContext,
Task<object> GetStaticFileResult(IRequest requestContext,
StaticFileResultOptions options);
}
}

View file

@ -5,14 +5,14 @@ namespace MediaBrowser.Model.Dlna
[Flags]
public enum DlnaFlags : ulong
{
/*! <i>Background</i> transfer mode.
For use with upload and download transfers to and from the server.
The primary difference between \ref DH_TransferMode_Interactive and
\ref DH_TransferMode_Bulk is that the latter assumes that the user
is not relying on the transfer for immediately rendering the content
and there are no issues with causing a buffer overflow if the
receiver uses TCP flow control to reduce total throughput.
*/
/*! <i>Background</i> transfer mode.
For use with upload and download transfers to and from the server.
The primary difference between \ref DH_TransferMode_Interactive and
\ref DH_TransferMode_Bulk is that the latter assumes that the user
is not relying on the transfer for immediately rendering the content
and there are no issues with causing a buffer overflow if the
receiver uses TCP flow control to reduce total throughput.
*/
BackgroundTransferMode = 1 << 22,
ByteBasedSeek = 1 << 29,
@ -21,10 +21,10 @@ namespace MediaBrowser.Model.Dlna
DlnaV15 = 1 << 20,
/*! <i>Interactive</i> transfer mode.
For best effort transfer of images and non-real-time transfers.
URIs with image content usually support \ref DH_TransferMode_Bulk too.
The primary difference between \ref DH_TransferMode_Interactive and
\ref DH_TransferMode_Bulk is that the former assumes that the
For best effort transfer of images and non-real-time transfers.
URIs with image content usually support \ref DH_TransferMode_Bulk too.
The primary difference between \ref DH_TransferMode_Interactive and
\ref DH_TransferMode_Bulk is that the former assumes that the
transfer is intended for immediate rendering.
*/
InteractiveTransferMode = 1 << 23,
@ -35,14 +35,14 @@ namespace MediaBrowser.Model.Dlna
SenderPaced = 1L << 31,
SnIncrease = 1 << 26,
/*! <i>Streaming</i> transfer mode.
The server transmits at a throughput sufficient for real-time playback of
audio or video. URIs with audio or video often support the
\ref DH_TransferMode_Interactive and \ref DH_TransferMode_Bulk transfer modes.
The most well-known exception to this general claim is for live streams.
/*! <i>Streaming</i> transfer mode.
The server transmits at a throughput sufficient for real-time playback of
audio or video. URIs with audio or video often support the
\ref DH_TransferMode_Interactive and \ref DH_TransferMode_Bulk transfer modes.
The most well-known exception to this general claim is for live streams.
*/
StreamingTransferMode = 1 << 24,
TimeBasedSeek = 1 << 30
}
}
}

View file

@ -7,14 +7,13 @@ namespace MediaBrowser.Model.Net
/// Implemented by components that can create a platform specific UDP socket implementation, and wrap it in the cross platform <see cref="ISocket"/> interface.
/// </summary>
public interface ISocketFactory
{
/// <summary>
/// Createa a new unicast socket using the specified local port number.
/// </summary>
/// <param name="localPort">The local port to bind to.</param>
/// <returns>A <see cref="ISocket"/> implementation.</returns>
ISocket CreateUdpSocket(int localPort);
{
/// <summary>
/// Createa a new unicast socket using the specified local port number.
/// </summary>
/// <param name="localPort">The local port to bind to.</param>
/// <returns>A <see cref="ISocket"/> implementation.</returns>
ISocket CreateUdpSocket(int localPort);
ISocket CreateUdpBroadcastSocket(int localPort);

View file

@ -5,16 +5,16 @@ namespace MediaBrowser.Model.Net
/// Used by the sockets wrapper to hold raw data received from a UDP socket.
/// </summary>
public sealed class SocketReceiveResult
{
/// <summary>
/// The buffer to place received data into.
/// </summary>
public byte[] Buffer { get; set; }
{
/// <summary>
/// The buffer to place received data into.
/// </summary>
public byte[] Buffer { get; set; }
/// <summary>
/// The number of bytes received.
/// </summary>
public int ReceivedBytes { get; set; }
/// <summary>
/// The number of bytes received.
/// </summary>
public int ReceivedBytes { get; set; }
/// <summary>
/// The <see cref="IpEndPointInfo"/> the data was received from.

View file

@ -9,516 +9,286 @@ namespace MediaBrowser.Model.Services
{
// Must be sorted
static readonly long[] entities = new long[] {
(long)'A' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'A' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'A' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'A' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'A' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24,
(long)'A' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24,
(long)'A' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'A' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'B' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'C' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16,
(long)'C' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'D' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16,
(long)'D' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'E' << 56 | (long)'T' << 48 | (long)'H' << 40,
(long)'E' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'E' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'E' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'E' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'E' << 56 | (long)'t' << 48 | (long)'a' << 40,
(long)'E' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'G' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'I' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'I' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'I' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'I' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'I' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'K' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24,
(long)'L' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16,
(long)'M' << 56 | (long)'u' << 48,
(long)'N' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'N' << 56 | (long)'u' << 48,
(long)'O' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'O' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'O' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'O' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'O' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24,
(long)'O' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'O' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16,
(long)'O' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'O' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'P' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'P' << 56 | (long)'i' << 48,
(long)'P' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24,
(long)'P' << 56 | (long)'s' << 48 | (long)'i' << 40,
(long)'R' << 56 | (long)'h' << 48 | (long)'o' << 40,
(long)'S' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16,
(long)'S' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'T' << 56 | (long)'H' << 48 | (long)'O' << 40 | (long)'R' << 32 | (long)'N' << 24,
(long)'T' << 56 | (long)'a' << 48 | (long)'u' << 40,
(long)'T' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'U' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'U' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'U' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'U' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'U' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'X' << 56 | (long)'i' << 48,
(long)'Y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'Y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'Z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'a' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'a' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'a' << 56 | (long)'c' << 48 | (long)'u' << 40 | (long)'t' << 32 | (long)'e' << 24,
(long)'a' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'a' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'a' << 56 | (long)'l' << 48 | (long)'e' << 40 | (long)'f' << 32 | (long)'s' << 24 | (long)'y' << 16 | (long)'m' << 8,
(long)'a' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24,
(long)'a' << 56 | (long)'m' << 48 | (long)'p' << 40,
(long)'a' << 56 | (long)'n' << 48 | (long)'d' << 40,
(long)'a' << 56 | (long)'n' << 48 | (long)'g' << 40,
(long)'a' << 56 | (long)'p' << 48 | (long)'o' << 40 | (long)'s' << 32,
(long)'a' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24,
(long)'a' << 56 | (long)'s' << 48 | (long)'y' << 40 | (long)'m' << 32 | (long)'p' << 24,
(long)'a' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'a' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'b' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'b' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'b' << 56 | (long)'r' << 48 | (long)'v' << 40 | (long)'b' << 32 | (long)'a' << 24 | (long)'r' << 16,
(long)'b' << 56 | (long)'u' << 48 | (long)'l' << 40 | (long)'l' << 32,
(long)'c' << 56 | (long)'a' << 48 | (long)'p' << 40,
(long)'c' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16,
(long)'c' << 56 | (long)'e' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'l' << 24,
(long)'c' << 56 | (long)'e' << 48 | (long)'n' << 40 | (long)'t' << 32,
(long)'c' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'c' << 56 | (long)'i' << 48 | (long)'r' << 40 | (long)'c' << 32,
(long)'c' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'b' << 32 | (long)'s' << 24,
(long)'c' << 56 | (long)'o' << 48 | (long)'n' << 40 | (long)'g' << 32,
(long)'c' << 56 | (long)'o' << 48 | (long)'p' << 40 | (long)'y' << 32,
(long)'c' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'r' << 24,
(long)'c' << 56 | (long)'u' << 48 | (long)'p' << 40,
(long)'c' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'n' << 16,
(long)'d' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'d' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16,
(long)'d' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'d' << 56 | (long)'e' << 48 | (long)'g' << 40,
(long)'d' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'d' << 56 | (long)'i' << 48 | (long)'a' << 40 | (long)'m' << 32 | (long)'s' << 24,
(long)'d' << 56 | (long)'i' << 48 | (long)'v' << 40 | (long)'i' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'e' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'e' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'e' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'e' << 56 | (long)'m' << 48 | (long)'p' << 40 | (long)'t' << 32 | (long)'y' << 24,
(long)'e' << 56 | (long)'m' << 48 | (long)'s' << 40 | (long)'p' << 32,
(long)'e' << 56 | (long)'n' << 48 | (long)'s' << 40 | (long)'p' << 32,
(long)'e' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'e' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'i' << 32 | (long)'v' << 24,
(long)'e' << 56 | (long)'t' << 48 | (long)'a' << 40,
(long)'e' << 56 | (long)'t' << 48 | (long)'h' << 40,
(long)'e' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'e' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'o' << 32,
(long)'e' << 56 | (long)'x' << 48 | (long)'i' << 40 | (long)'s' << 32 | (long)'t' << 24,
(long)'f' << 56 | (long)'n' << 48 | (long)'o' << 40 | (long)'f' << 32,
(long)'f' << 56 | (long)'o' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'l' << 24 | (long)'l' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'2' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'4' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'3' << 24 | (long)'4' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'l' << 24,
(long)'g' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'g' << 56 | (long)'e' << 48,
(long)'g' << 56 | (long)'t' << 48,
(long)'h' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'h' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'h' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'t' << 24 | (long)'s' << 16,
(long)'h' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'l' << 32 | (long)'i' << 24 | (long)'p' << 16,
(long)'i' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'i' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'i' << 56 | (long)'e' << 48 | (long)'x' << 40 | (long)'c' << 32 | (long)'l' << 24,
(long)'i' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'i' << 56 | (long)'m' << 48 | (long)'a' << 40 | (long)'g' << 32 | (long)'e' << 24,
(long)'i' << 56 | (long)'n' << 48 | (long)'f' << 40 | (long)'i' << 32 | (long)'n' << 24,
(long)'i' << 56 | (long)'n' << 48 | (long)'t' << 40,
(long)'i' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'i' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'e' << 32 | (long)'s' << 24 | (long)'t' << 16,
(long)'i' << 56 | (long)'s' << 48 | (long)'i' << 40 | (long)'n' << 32,
(long)'i' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'k' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24,
(long)'l' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'l' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16,
(long)'l' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32,
(long)'l' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'l' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'l' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24,
(long)'l' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'l' << 56 | (long)'e' << 48,
(long)'l' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16,
(long)'l' << 56 | (long)'o' << 48 | (long)'w' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'t' << 16,
(long)'l' << 56 | (long)'o' << 48 | (long)'z' << 40,
(long)'l' << 56 | (long)'r' << 48 | (long)'m' << 40,
(long)'l' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16,
(long)'l' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'l' << 56 | (long)'t' << 48,
(long)'m' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'r' << 32,
(long)'m' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24,
(long)'m' << 56 | (long)'i' << 48 | (long)'c' << 40 | (long)'r' << 32 | (long)'o' << 24,
(long)'m' << 56 | (long)'i' << 48 | (long)'d' << 40 | (long)'d' << 32 | (long)'o' << 24 | (long)'t' << 16,
(long)'m' << 56 | (long)'i' << 48 | (long)'n' << 40 | (long)'u' << 32 | (long)'s' << 24,
(long)'m' << 56 | (long)'u' << 48,
(long)'n' << 56 | (long)'a' << 48 | (long)'b' << 40 | (long)'l' << 32 | (long)'a' << 24,
(long)'n' << 56 | (long)'b' << 48 | (long)'s' << 40 | (long)'p' << 32,
(long)'n' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24,
(long)'n' << 56 | (long)'e' << 48,
(long)'n' << 56 | (long)'i' << 48,
(long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40,
(long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'i' << 32 | (long)'n' << 24,
(long)'n' << 56 | (long)'s' << 48 | (long)'u' << 40 | (long)'b' << 32,
(long)'n' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'n' << 56 | (long)'u' << 48,
(long)'o' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'o' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'o' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'o' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'o' << 56 | (long)'l' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'e' << 24,
(long)'o' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24,
(long)'o' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'o' << 56 | (long)'p' << 48 | (long)'l' << 40 | (long)'u' << 32 | (long)'s' << 24,
(long)'o' << 56 | (long)'r' << 48,
(long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'f' << 32,
(long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'m' << 32,
(long)'o' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16,
(long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24 | (long)'s' << 16,
(long)'o' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'a' << 32,
(long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'t' << 32,
(long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'m' << 32 | (long)'i' << 24 | (long)'l' << 16,
(long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'p' << 32,
(long)'p' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'p' << 56 | (long)'i' << 48,
(long)'p' << 56 | (long)'i' << 48 | (long)'v' << 40,
(long)'p' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'s' << 32 | (long)'m' << 24 | (long)'n' << 16,
(long)'p' << 56 | (long)'o' << 48 | (long)'u' << 40 | (long)'n' << 32 | (long)'d' << 24,
(long)'p' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24,
(long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'d' << 32,
(long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'p' << 32,
(long)'p' << 56 | (long)'s' << 48 | (long)'i' << 40,
(long)'q' << 56 | (long)'u' << 48 | (long)'o' << 40 | (long)'t' << 32,
(long)'r' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'r' << 56 | (long)'a' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'c' << 24,
(long)'r' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32,
(long)'r' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'r' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'r' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24,
(long)'r' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'r' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'l' << 32,
(long)'r' << 56 | (long)'e' << 48 | (long)'g' << 40,
(long)'r' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16,
(long)'r' << 56 | (long)'h' << 48 | (long)'o' << 40,
(long)'r' << 56 | (long)'l' << 48 | (long)'m' << 40,
(long)'r' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16,
(long)'r' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'s' << 56 | (long)'b' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'s' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16,
(long)'s' << 56 | (long)'d' << 48 | (long)'o' << 40 | (long)'t' << 32,
(long)'s' << 56 | (long)'e' << 48 | (long)'c' << 40 | (long)'t' << 32,
(long)'s' << 56 | (long)'h' << 48 | (long)'y' << 40,
(long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24 | (long)'f' << 16,
(long)'s' << 56 | (long)'i' << 48 | (long)'m' << 40,
(long)'s' << 56 | (long)'p' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24 | (long)'s' << 16,
(long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40,
(long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40 | (long)'e' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'m' << 40,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'1' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'2' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'3' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'e' << 32,
(long)'s' << 56 | (long)'z' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'t' << 56 | (long)'a' << 48 | (long)'u' << 40,
(long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'4' << 16,
(long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24 | (long)'s' << 16 | (long)'y' << 8 | (long)'m' << 0,
(long)'t' << 56 | (long)'h' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'s' << 24 | (long)'p' << 16,
(long)'t' << 56 | (long)'h' << 48 | (long)'o' << 40 | (long)'r' << 32 | (long)'n' << 24,
(long)'t' << 56 | (long)'i' << 48 | (long)'l' << 40 | (long)'d' << 32 | (long)'e' << 24,
(long)'t' << 56 | (long)'i' << 48 | (long)'m' << 40 | (long)'e' << 32 | (long)'s' << 24,
(long)'t' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24,
(long)'u' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'u' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'u' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'u' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'u' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'u' << 56 | (long)'m' << 48 | (long)'l' << 40,
(long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'h' << 24,
(long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'u' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'w' << 56 | (long)'e' << 48 | (long)'i' << 40 | (long)'e' << 32 | (long)'r' << 24 | (long)'p' << 16,
(long)'x' << 56 | (long)'i' << 48,
(long)'y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'y' << 56 | (long)'e' << 48 | (long)'n' << 40,
(long)'y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'z' << 56 | (long)'w' << 48 | (long)'j' << 40,
(long)'z' << 56 | (long)'w' << 48 | (long)'n' << 40 | (long)'j' << 32
};
(long)'A' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'A' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'A' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'A' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'A' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24,
(long)'A' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24,
(long)'A' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'A' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'B' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'C' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16,
(long)'C' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'D' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16,
(long)'D' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'E' << 56 | (long)'T' << 48 | (long)'H' << 40,
(long)'E' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'E' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'E' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'E' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'E' << 56 | (long)'t' << 48 | (long)'a' << 40,
(long)'E' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'G' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'I' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'I' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'I' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'I' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'I' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'K' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24,
(long)'L' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16,
(long)'M' << 56 | (long)'u' << 48,
(long)'N' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'N' << 56 | (long)'u' << 48,
(long)'O' << 56 | (long)'E' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'O' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'O' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'O' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'O' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24,
(long)'O' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'O' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16,
(long)'O' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'O' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'P' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'P' << 56 | (long)'i' << 48,
(long)'P' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24,
(long)'P' << 56 | (long)'s' << 48 | (long)'i' << 40,
(long)'R' << 56 | (long)'h' << 48 | (long)'o' << 40,
(long)'S' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16,
(long)'S' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'T' << 56 | (long)'H' << 48 | (long)'O' << 40 | (long)'R' << 32 | (long)'N' << 24,
(long)'T' << 56 | (long)'a' << 48 | (long)'u' << 40,
(long)'T' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'U' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'U' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'U' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'U' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'U' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'X' << 56 | (long)'i' << 48,
(long)'Y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'Y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'Z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'a' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'a' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'a' << 56 | (long)'c' << 48 | (long)'u' << 40 | (long)'t' << 32 | (long)'e' << 24,
(long)'a' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'a' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'a' << 56 | (long)'l' << 48 | (long)'e' << 40 | (long)'f' << 32 | (long)'s' << 24 | (long)'y' << 16 | (long)'m' << 8,
(long)'a' << 56 | (long)'l' << 48 | (long)'p' << 40 | (long)'h' << 32 | (long)'a' << 24,
(long)'a' << 56 | (long)'m' << 48 | (long)'p' << 40,
(long)'a' << 56 | (long)'n' << 48 | (long)'d' << 40,
(long)'a' << 56 | (long)'n' << 48 | (long)'g' << 40,
(long)'a' << 56 | (long)'p' << 48 | (long)'o' << 40 | (long)'s' << 32,
(long)'a' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'g' << 24,
(long)'a' << 56 | (long)'s' << 48 | (long)'y' << 40 | (long)'m' << 32 | (long)'p' << 24,
(long)'a' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'a' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'b' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'b' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'b' << 56 | (long)'r' << 48 | (long)'v' << 40 | (long)'b' << 32 | (long)'a' << 24 | (long)'r' << 16,
(long)'b' << 56 | (long)'u' << 48 | (long)'l' << 40 | (long)'l' << 32,
(long)'c' << 56 | (long)'a' << 48 | (long)'p' << 40,
(long)'c' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'d' << 32 | (long)'i' << 24 | (long)'l' << 16,
(long)'c' << 56 | (long)'e' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'l' << 24,
(long)'c' << 56 | (long)'e' << 48 | (long)'n' << 40 | (long)'t' << 32,
(long)'c' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'c' << 56 | (long)'i' << 48 | (long)'r' << 40 | (long)'c' << 32,
(long)'c' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'b' << 32 | (long)'s' << 24,
(long)'c' << 56 | (long)'o' << 48 | (long)'n' << 40 | (long)'g' << 32,
(long)'c' << 56 | (long)'o' << 48 | (long)'p' << 40 | (long)'y' << 32,
(long)'c' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'r' << 24,
(long)'c' << 56 | (long)'u' << 48 | (long)'p' << 40,
(long)'c' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'n' << 16,
(long)'d' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'d' << 56 | (long)'a' << 48 | (long)'g' << 40 | (long)'g' << 32 | (long)'e' << 24 | (long)'r' << 16,
(long)'d' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'d' << 56 | (long)'e' << 48 | (long)'g' << 40,
(long)'d' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'d' << 56 | (long)'i' << 48 | (long)'a' << 40 | (long)'m' << 32 | (long)'s' << 24,
(long)'d' << 56 | (long)'i' << 48 | (long)'v' << 40 | (long)'i' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'e' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'e' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'e' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'e' << 56 | (long)'m' << 48 | (long)'p' << 40 | (long)'t' << 32 | (long)'y' << 24,
(long)'e' << 56 | (long)'m' << 48 | (long)'s' << 40 | (long)'p' << 32,
(long)'e' << 56 | (long)'n' << 48 | (long)'s' << 40 | (long)'p' << 32,
(long)'e' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'e' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'i' << 32 | (long)'v' << 24,
(long)'e' << 56 | (long)'t' << 48 | (long)'a' << 40,
(long)'e' << 56 | (long)'t' << 48 | (long)'h' << 40,
(long)'e' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'e' << 56 | (long)'u' << 48 | (long)'r' << 40 | (long)'o' << 32,
(long)'e' << 56 | (long)'x' << 48 | (long)'i' << 40 | (long)'s' << 32 | (long)'t' << 24,
(long)'f' << 56 | (long)'n' << 48 | (long)'o' << 40 | (long)'f' << 32,
(long)'f' << 56 | (long)'o' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'l' << 24 | (long)'l' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'2' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'1' << 24 | (long)'4' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'c' << 32 | (long)'3' << 24 | (long)'4' << 16,
(long)'f' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'l' << 24,
(long)'g' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'g' << 56 | (long)'e' << 48,
(long)'g' << 56 | (long)'t' << 48,
(long)'h' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'h' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'h' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'t' << 24 | (long)'s' << 16,
(long)'h' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'l' << 32 | (long)'i' << 24 | (long)'p' << 16,
(long)'i' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'i' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'i' << 56 | (long)'e' << 48 | (long)'x' << 40 | (long)'c' << 32 | (long)'l' << 24,
(long)'i' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'i' << 56 | (long)'m' << 48 | (long)'a' << 40 | (long)'g' << 32 | (long)'e' << 24,
(long)'i' << 56 | (long)'n' << 48 | (long)'f' << 40 | (long)'i' << 32 | (long)'n' << 24,
(long)'i' << 56 | (long)'n' << 48 | (long)'t' << 40,
(long)'i' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'i' << 56 | (long)'q' << 48 | (long)'u' << 40 | (long)'e' << 32 | (long)'s' << 24 | (long)'t' << 16,
(long)'i' << 56 | (long)'s' << 48 | (long)'i' << 40 | (long)'n' << 32,
(long)'i' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'k' << 56 | (long)'a' << 48 | (long)'p' << 40 | (long)'p' << 32 | (long)'a' << 24,
(long)'l' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'l' << 56 | (long)'a' << 48 | (long)'m' << 40 | (long)'b' << 32 | (long)'d' << 24 | (long)'a' << 16,
(long)'l' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32,
(long)'l' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'l' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'l' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24,
(long)'l' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'l' << 56 | (long)'e' << 48,
(long)'l' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16,
(long)'l' << 56 | (long)'o' << 48 | (long)'w' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'t' << 16,
(long)'l' << 56 | (long)'o' << 48 | (long)'z' << 40,
(long)'l' << 56 | (long)'r' << 48 | (long)'m' << 40,
(long)'l' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16,
(long)'l' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'l' << 56 | (long)'t' << 48,
(long)'m' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'r' << 32,
(long)'m' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24,
(long)'m' << 56 | (long)'i' << 48 | (long)'c' << 40 | (long)'r' << 32 | (long)'o' << 24,
(long)'m' << 56 | (long)'i' << 48 | (long)'d' << 40 | (long)'d' << 32 | (long)'o' << 24 | (long)'t' << 16,
(long)'m' << 56 | (long)'i' << 48 | (long)'n' << 40 | (long)'u' << 32 | (long)'s' << 24,
(long)'m' << 56 | (long)'u' << 48,
(long)'n' << 56 | (long)'a' << 48 | (long)'b' << 40 | (long)'l' << 32 | (long)'a' << 24,
(long)'n' << 56 | (long)'b' << 48 | (long)'s' << 40 | (long)'p' << 32,
(long)'n' << 56 | (long)'d' << 48 | (long)'a' << 40 | (long)'s' << 32 | (long)'h' << 24,
(long)'n' << 56 | (long)'e' << 48,
(long)'n' << 56 | (long)'i' << 48,
(long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40,
(long)'n' << 56 | (long)'o' << 48 | (long)'t' << 40 | (long)'i' << 32 | (long)'n' << 24,
(long)'n' << 56 | (long)'s' << 48 | (long)'u' << 40 | (long)'b' << 32,
(long)'n' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'n' << 56 | (long)'u' << 48,
(long)'o' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'o' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'o' << 56 | (long)'e' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'o' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'o' << 56 | (long)'l' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'e' << 24,
(long)'o' << 56 | (long)'m' << 48 | (long)'e' << 40 | (long)'g' << 32 | (long)'a' << 24,
(long)'o' << 56 | (long)'m' << 48 | (long)'i' << 40 | (long)'c' << 32 | (long)'r' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'o' << 56 | (long)'p' << 48 | (long)'l' << 40 | (long)'u' << 32 | (long)'s' << 24,
(long)'o' << 56 | (long)'r' << 48,
(long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'f' << 32,
(long)'o' << 56 | (long)'r' << 48 | (long)'d' << 40 | (long)'m' << 32,
(long)'o' << 56 | (long)'s' << 48 | (long)'l' << 40 | (long)'a' << 32 | (long)'s' << 24 | (long)'h' << 16,
(long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'l' << 32 | (long)'d' << 24 | (long)'e' << 16,
(long)'o' << 56 | (long)'t' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24 | (long)'s' << 16,
(long)'o' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'a' << 32,
(long)'p' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'t' << 32,
(long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'m' << 32 | (long)'i' << 24 | (long)'l' << 16,
(long)'p' << 56 | (long)'e' << 48 | (long)'r' << 40 | (long)'p' << 32,
(long)'p' << 56 | (long)'h' << 48 | (long)'i' << 40,
(long)'p' << 56 | (long)'i' << 48,
(long)'p' << 56 | (long)'i' << 48 | (long)'v' << 40,
(long)'p' << 56 | (long)'l' << 48 | (long)'u' << 40 | (long)'s' << 32 | (long)'m' << 24 | (long)'n' << 16,
(long)'p' << 56 | (long)'o' << 48 | (long)'u' << 40 | (long)'n' << 32 | (long)'d' << 24,
(long)'p' << 56 | (long)'r' << 48 | (long)'i' << 40 | (long)'m' << 32 | (long)'e' << 24,
(long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'d' << 32,
(long)'p' << 56 | (long)'r' << 48 | (long)'o' << 40 | (long)'p' << 32,
(long)'p' << 56 | (long)'s' << 48 | (long)'i' << 40,
(long)'q' << 56 | (long)'u' << 48 | (long)'o' << 40 | (long)'t' << 32,
(long)'r' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'r' << 56 | (long)'a' << 48 | (long)'d' << 40 | (long)'i' << 32 | (long)'c' << 24,
(long)'r' << 56 | (long)'a' << 48 | (long)'n' << 40 | (long)'g' << 32,
(long)'r' << 56 | (long)'a' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'r' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'r' << 56 | (long)'c' << 48 | (long)'e' << 40 | (long)'i' << 32 | (long)'l' << 24,
(long)'r' << 56 | (long)'d' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'r' << 56 | (long)'e' << 48 | (long)'a' << 40 | (long)'l' << 32,
(long)'r' << 56 | (long)'e' << 48 | (long)'g' << 40,
(long)'r' << 56 | (long)'f' << 48 | (long)'l' << 40 | (long)'o' << 32 | (long)'o' << 24 | (long)'r' << 16,
(long)'r' << 56 | (long)'h' << 48 | (long)'o' << 40,
(long)'r' << 56 | (long)'l' << 48 | (long)'m' << 40,
(long)'r' << 56 | (long)'s' << 48 | (long)'a' << 40 | (long)'q' << 32 | (long)'u' << 24 | (long)'o' << 16,
(long)'r' << 56 | (long)'s' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'s' << 56 | (long)'b' << 48 | (long)'q' << 40 | (long)'u' << 32 | (long)'o' << 24,
(long)'s' << 56 | (long)'c' << 48 | (long)'a' << 40 | (long)'r' << 32 | (long)'o' << 24 | (long)'n' << 16,
(long)'s' << 56 | (long)'d' << 48 | (long)'o' << 40 | (long)'t' << 32,
(long)'s' << 56 | (long)'e' << 48 | (long)'c' << 40 | (long)'t' << 32,
(long)'s' << 56 | (long)'h' << 48 | (long)'y' << 40,
(long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24,
(long)'s' << 56 | (long)'i' << 48 | (long)'g' << 40 | (long)'m' << 32 | (long)'a' << 24 | (long)'f' << 16,
(long)'s' << 56 | (long)'i' << 48 | (long)'m' << 40,
(long)'s' << 56 | (long)'p' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24 | (long)'s' << 16,
(long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40,
(long)'s' << 56 | (long)'u' << 48 | (long)'b' << 40 | (long)'e' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'m' << 40,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'1' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'2' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'3' << 32,
(long)'s' << 56 | (long)'u' << 48 | (long)'p' << 40 | (long)'e' << 32,
(long)'s' << 56 | (long)'z' << 48 | (long)'l' << 40 | (long)'i' << 32 | (long)'g' << 24,
(long)'t' << 56 | (long)'a' << 48 | (long)'u' << 40,
(long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'r' << 32 | (long)'e' << 24 | (long)'4' << 16,
(long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24,
(long)'t' << 56 | (long)'h' << 48 | (long)'e' << 40 | (long)'t' << 32 | (long)'a' << 24 | (long)'s' << 16 | (long)'y' << 8 | (long)'m' << 0,
(long)'t' << 56 | (long)'h' << 48 | (long)'i' << 40 | (long)'n' << 32 | (long)'s' << 24 | (long)'p' << 16,
(long)'t' << 56 | (long)'h' << 48 | (long)'o' << 40 | (long)'r' << 32 | (long)'n' << 24,
(long)'t' << 56 | (long)'i' << 48 | (long)'l' << 40 | (long)'d' << 32 | (long)'e' << 24,
(long)'t' << 56 | (long)'i' << 48 | (long)'m' << 40 | (long)'e' << 32 | (long)'s' << 24,
(long)'t' << 56 | (long)'r' << 48 | (long)'a' << 40 | (long)'d' << 32 | (long)'e' << 24,
(long)'u' << 56 | (long)'A' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'u' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'u' << 56 | (long)'a' << 48 | (long)'r' << 40 | (long)'r' << 32,
(long)'u' << 56 | (long)'c' << 48 | (long)'i' << 40 | (long)'r' << 32 | (long)'c' << 24,
(long)'u' << 56 | (long)'g' << 48 | (long)'r' << 40 | (long)'a' << 32 | (long)'v' << 24 | (long)'e' << 16,
(long)'u' << 56 | (long)'m' << 48 | (long)'l' << 40,
(long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'h' << 24,
(long)'u' << 56 | (long)'p' << 48 | (long)'s' << 40 | (long)'i' << 32 | (long)'l' << 24 | (long)'o' << 16 | (long)'n' << 8,
(long)'u' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'w' << 56 | (long)'e' << 48 | (long)'i' << 40 | (long)'e' << 32 | (long)'r' << 24 | (long)'p' << 16,
(long)'x' << 56 | (long)'i' << 48,
(long)'y' << 56 | (long)'a' << 48 | (long)'c' << 40 | (long)'u' << 32 | (long)'t' << 24 | (long)'e' << 16,
(long)'y' << 56 | (long)'e' << 48 | (long)'n' << 40,
(long)'y' << 56 | (long)'u' << 48 | (long)'m' << 40 | (long)'l' << 32,
(long)'z' << 56 | (long)'e' << 48 | (long)'t' << 40 | (long)'a' << 32,
(long)'z' << 56 | (long)'w' << 48 | (long)'j' << 40,
(long)'z' << 56 | (long)'w' << 48 | (long)'n' << 40 | (long)'j' << 32
};
static readonly char[] entities_values = new char[] {
'\u00C6',
'\u00C1',
'\u00C2',
'\u00C0',
'\u0391',
'\u00C5',
'\u00C3',
'\u00C4',
'\u0392',
'\u00C7',
'\u03A7',
'\u2021',
'\u0394',
'\u00D0',
'\u00C9',
'\u00CA',
'\u00C8',
'\u0395',
'\u0397',
'\u00CB',
'\u0393',
'\u00CD',
'\u00CE',
'\u00CC',
'\u0399',
'\u00CF',
'\u039A',
'\u039B',
'\u039C',
'\u00D1',
'\u039D',
'\u0152',
'\u00D3',
'\u00D4',
'\u00D2',
'\u03A9',
'\u039F',
'\u00D8',
'\u00D5',
'\u00D6',
'\u03A6',
'\u03A0',
'\u2033',
'\u03A8',
'\u03A1',
'\u0160',
'\u03A3',
'\u00DE',
'\u03A4',
'\u0398',
'\u00DA',
'\u00DB',
'\u00D9',
'\u03A5',
'\u00DC',
'\u039E',
'\u00DD',
'\u0178',
'\u0396',
'\u00E1',
'\u00E2',
'\u00B4',
'\u00E6',
'\u00E0',
'\u2135',
'\u03B1',
'\u0026',
'\u2227',
'\u2220',
'\u0027',
'\u00E5',
'\u2248',
'\u00E3',
'\u00E4',
'\u201E',
'\u03B2',
'\u00A6',
'\u2022',
'\u2229',
'\u00E7',
'\u00B8',
'\u00A2',
'\u03C7',
'\u02C6',
'\u2663',
'\u2245',
'\u00A9',
'\u21B5',
'\u222A',
'\u00A4',
'\u21D3',
'\u2020',
'\u2193',
'\u00B0',
'\u03B4',
'\u2666',
'\u00F7',
'\u00E9',
'\u00EA',
'\u00E8',
'\u2205',
'\u2003',
'\u2002',
'\u03B5',
'\u2261',
'\u03B7',
'\u00F0',
'\u00EB',
'\u20AC',
'\u2203',
'\u0192',
'\u2200',
'\u00BD',
'\u00BC',
'\u00BE',
'\u2044',
'\u03B3',
'\u2265',
'\u003E',
'\u21D4',
'\u2194',
'\u2665',
'\u2026',
'\u00ED',
'\u00EE',
'\u00A1',
'\u00EC',
'\u2111',
'\u221E',
'\u222B',
'\u03B9',
'\u00BF',
'\u2208',
'\u00EF',
'\u03BA',
'\u21D0',
'\u03BB',
'\u2329',
'\u00AB',
'\u2190',
'\u2308',
'\u201C',
'\u2264',
'\u230A',
'\u2217',
'\u25CA',
'\u200E',
'\u2039',
'\u2018',
'\u003C',
'\u00AF',
'\u2014',
'\u00B5',
'\u00B7',
'\u2212',
'\u03BC',
'\u2207',
'\u00A0',
'\u2013',
'\u2260',
'\u220B',
'\u00AC',
'\u2209',
'\u2284',
'\u00F1',
'\u03BD',
'\u00F3',
'\u00F4',
'\u0153',
'\u00F2',
'\u203E',
'\u03C9',
'\u03BF',
'\u2295',
'\u2228',
'\u00AA',
'\u00BA',
'\u00F8',
'\u00F5',
'\u2297',
'\u00F6',
'\u00B6',
'\u2202',
'\u2030',
'\u22A5',
'\u03C6',
'\u03C0',
'\u03D6',
'\u00B1',
'\u00A3',
'\u2032',
'\u220F',
'\u221D',
'\u03C8',
'\u0022',
'\u21D2',
'\u221A',
'\u232A',
'\u00BB',
'\u2192',
'\u2309',
'\u201D',
'\u211C',
'\u00AE',
'\u230B',
'\u03C1',
'\u200F',
'\u203A',
'\u2019',
'\u201A',
'\u0161',
'\u22C5',
'\u00A7',
'\u00AD',
'\u03C3',
'\u03C2',
'\u223C',
'\u2660',
'\u2282',
'\u2286',
'\u2211',
'\u2283',
'\u00B9',
'\u00B2',
'\u00B3',
'\u2287',
'\u00DF',
'\u03C4',
'\u2234',
'\u03B8',
'\u03D1',
'\u2009',
'\u00FE',
'\u02DC',
'\u00D7',
'\u2122',
'\u21D1',
'\u00FA',
'\u2191',
'\u00FB',
'\u00F9',
'\u00A8',
'\u03D2',
'\u03C5',
'\u00FC',
'\u2118',
'\u03BE',
'\u00FD',
'\u00A5',
'\u00FF',
'\u03B6',
'\u200D',
'\u200C'
};
'\u00C6', '\u00C1', '\u00C2', '\u00C0', '\u0391', '\u00C5', '\u00C3', '\u00C4', '\u0392', '\u00C7', '\u03A7',
'\u2021', '\u0394', '\u00D0', '\u00C9', '\u00CA', '\u00C8', '\u0395', '\u0397', '\u00CB', '\u0393', '\u00CD',
'\u00CE', '\u00CC', '\u0399', '\u00CF', '\u039A', '\u039B', '\u039C', '\u00D1', '\u039D', '\u0152', '\u00D3',
'\u00D4', '\u00D2', '\u03A9', '\u039F', '\u00D8', '\u00D5', '\u00D6', '\u03A6', '\u03A0', '\u2033', '\u03A8',
'\u03A1', '\u0160', '\u03A3', '\u00DE', '\u03A4', '\u0398', '\u00DA', '\u00DB', '\u00D9', '\u03A5', '\u00DC',
'\u039E', '\u00DD', '\u0178', '\u0396', '\u00E1', '\u00E2', '\u00B4', '\u00E6', '\u00E0', '\u2135', '\u03B1',
'\u0026', '\u2227', '\u2220', '\u0027', '\u00E5', '\u2248', '\u00E3', '\u00E4', '\u201E', '\u03B2', '\u00A6',
'\u2022', '\u2229', '\u00E7', '\u00B8', '\u00A2', '\u03C7', '\u02C6', '\u2663', '\u2245', '\u00A9', '\u21B5',
'\u222A', '\u00A4', '\u21D3', '\u2020', '\u2193', '\u00B0', '\u03B4', '\u2666', '\u00F7', '\u00E9', '\u00EA',
'\u00E8', '\u2205', '\u2003', '\u2002', '\u03B5', '\u2261', '\u03B7', '\u00F0', '\u00EB', '\u20AC', '\u2203',
'\u0192', '\u2200', '\u00BD', '\u00BC', '\u00BE', '\u2044', '\u03B3', '\u2265', '\u003E', '\u21D4', '\u2194',
'\u2665', '\u2026', '\u00ED', '\u00EE', '\u00A1', '\u00EC', '\u2111', '\u221E', '\u222B', '\u03B9', '\u00BF',
'\u2208', '\u00EF', '\u03BA', '\u21D0', '\u03BB', '\u2329', '\u00AB', '\u2190', '\u2308', '\u201C', '\u2264',
'\u230A', '\u2217', '\u25CA', '\u200E', '\u2039', '\u2018', '\u003C', '\u00AF', '\u2014', '\u00B5', '\u00B7',
'\u2212', '\u03BC', '\u2207', '\u00A0', '\u2013', '\u2260', '\u220B', '\u00AC', '\u2209', '\u2284', '\u00F1',
'\u03BD', '\u00F3', '\u00F4', '\u0153', '\u00F2', '\u203E', '\u03C9', '\u03BF', '\u2295', '\u2228', '\u00AA',
'\u00BA', '\u00F8', '\u00F5', '\u2297', '\u00F6', '\u00B6', '\u2202', '\u2030', '\u22A5', '\u03C6', '\u03C0',
'\u03D6', '\u00B1', '\u00A3', '\u2032', '\u220F', '\u221D', '\u03C8', '\u0022', '\u21D2', '\u221A', '\u232A',
'\u00BB', '\u2192', '\u2309', '\u201D', '\u211C', '\u00AE', '\u230B', '\u03C1', '\u200F', '\u203A', '\u2019',
'\u201A', '\u0161', '\u22C5', '\u00A7', '\u00AD', '\u03C3', '\u03C2', '\u223C', '\u2660', '\u2282', '\u2286',
'\u2211', '\u2283', '\u00B9', '\u00B2', '\u00B3', '\u2287', '\u00DF', '\u03C4', '\u2234', '\u03B8', '\u03D1',
'\u2009', '\u00FE', '\u02DC', '\u00D7', '\u2122', '\u21D1', '\u00FA', '\u2191', '\u00FB', '\u00F9', '\u00A8',
'\u03D2', '\u03C5', '\u00FC', '\u2118', '\u03BE', '\u00FD', '\u00A5', '\u00FF', '\u03B6', '\u200D', '\u200C'
};
#region Methods

View file

@ -6,12 +6,12 @@ namespace MediaBrowser.Model.Services
public class RouteAttribute : Attribute
{
/// <summary>
/// <para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
/// <para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
/// </summary>
/// <param name="path">
/// <para>The path template to map to the request. See
/// <see cref="Path">RouteAttribute.Path</see>
/// for details on the correct format.</para>
/// <para>The path template to map to the request. See
/// <see cref="Path">RouteAttribute.Path</see>
/// for details on the correct format.</para>
/// </param>
public RouteAttribute(string path)
: this(path, null)
@ -19,15 +19,15 @@ namespace MediaBrowser.Model.Services
}
/// <summary>
/// <para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
/// <para>Initializes an instance of the <see cref="RouteAttribute"/> class.</para>
/// </summary>
/// <param name="path">
/// <para>The path template to map to the request. See
/// <see cref="Path">RouteAttribute.Path</see>
/// for details on the correct format.</para>
/// <para>The path template to map to the request. See
/// <see cref="Path">RouteAttribute.Path</see>
/// for details on the correct format.</para>
/// </param>
/// <param name="verbs">A comma-delimited list of HTTP verbs supported by the
/// service. If unspecified, all verbs are assumed to be supported.</param>
/// <param name="verbs">A comma-delimited list of HTTP verbs supported by the
/// service. If unspecified, all verbs are assumed to be supported.</param>
public RouteAttribute(string path, string verbs)
{
Path = path;
@ -35,51 +35,51 @@ namespace MediaBrowser.Model.Services
}
/// <summary>
/// Gets or sets the path template to be mapped to the request.
/// Gets or sets the path template to be mapped to the request.
/// </summary>
/// <value>
/// A <see cref="String"/> value providing the path mapped to
/// the request. Never <see langword="null"/>.
/// A <see cref="String"/> value providing the path mapped to
/// the request. Never <see langword="null"/>.
/// </value>
/// <remarks>
/// <para>Some examples of valid paths are:</para>
///
/// <list>
/// <item>"/Inventory"</item>
/// <item>"/Inventory/{Category}/{ItemId}"</item>
/// <item>"/Inventory/{ItemPath*}"</item>
/// </list>
///
/// <para>Variables are specified within "{}"
/// brackets. Each variable in the path is mapped to the same-named property
/// on the request DTO. At runtime, ServiceStack will parse the
/// request URL, extract the variable values, instantiate the request DTO,
/// and assign the variable values into the corresponding request properties,
/// prior to passing the request DTO to the service object for processing.</para>
///
/// <para>It is not necessary to specify all request properties as
/// variables in the path. For unspecified properties, callers may provide
/// values in the query string. For example: the URL
/// "http://services/Inventory?Category=Books&amp;ItemId=12345" causes the same
/// request DTO to be processed as "http://services/Inventory/Books/12345",
/// provided that the paths "/Inventory" (which supports the first URL) and
/// "/Inventory/{Category}/{ItemId}" (which supports the second URL)
/// are both mapped to the request DTO.</para>
///
/// <para>Please note that while it is possible to specify property values
/// in the query string, it is generally considered to be less RESTful and
/// less desirable than to specify them as variables in the path. Using the
/// query string to specify property values may also interfere with HTTP
/// caching.</para>
///
/// <para>The final variable in the path may contain a "*" suffix
/// to grab all remaining segments in the path portion of the request URL and assign
/// them to a single property on the request DTO.
/// For example, if the path "/Inventory/{ItemPath*}" is mapped to the request DTO,
/// then the request URL "http://services/Inventory/Books/12345" will result
/// in a request DTO whose ItemPath property contains "Books/12345".
/// You may only specify one such variable in the path, and it must be positioned at
/// the end of the path.</para>
/// <para>Some examples of valid paths are:</para>
///
/// <list>
/// <item>"/Inventory"</item>
/// <item>"/Inventory/{Category}/{ItemId}"</item>
/// <item>"/Inventory/{ItemPath*}"</item>
/// </list>
///
/// <para>Variables are specified within "{}"
/// brackets. Each variable in the path is mapped to the same-named property
/// on the request DTO. At runtime, ServiceStack will parse the
/// request URL, extract the variable values, instantiate the request DTO,
/// and assign the variable values into the corresponding request properties,
/// prior to passing the request DTO to the service object for processing.</para>
///
/// <para>It is not necessary to specify all request properties as
/// variables in the path. For unspecified properties, callers may provide
/// values in the query string. For example: the URL
/// "http://services/Inventory?Category=Books&amp;ItemId=12345" causes the same
/// request DTO to be processed as "http://services/Inventory/Books/12345",
/// provided that the paths "/Inventory" (which supports the first URL) and
/// "/Inventory/{Category}/{ItemId}" (which supports the second URL)
/// are both mapped to the request DTO.</para>
///
/// <para>Please note that while it is possible to specify property values
/// in the query string, it is generally considered to be less RESTful and
/// less desirable than to specify them as variables in the path. Using the
/// query string to specify property values may also interfere with HTTP
/// caching.</para>
///
/// <para>The final variable in the path may contain a "*" suffix
/// to grab all remaining segments in the path portion of the request URL and assign
/// them to a single property on the request DTO.
/// For example, if the path "/Inventory/{ItemPath*}" is mapped to the request DTO,
/// then the request URL "http://services/Inventory/Books/12345" will result
/// in a request DTO whose ItemPath property contains "Books/12345".
/// You may only specify one such variable in the path, and it must be positioned at
/// the end of the path.</para>
/// </remarks>
public string Path { get; set; }
@ -93,22 +93,22 @@ namespace MediaBrowser.Model.Services
public bool IsHidden { get; set; }
/// <summary>
/// Gets or sets longer text to explain the behaviour of the route.
/// Gets or sets longer text to explain the behaviour of the route.
/// </summary>
public string Notes { get; set; }
/// <summary>
/// Gets or sets a comma-delimited list of HTTP verbs supported by the service, such as
/// "GET,PUT,POST,DELETE".
/// Gets or sets a comma-delimited list of HTTP verbs supported by the service, such as
/// "GET,PUT,POST,DELETE".
/// </summary>
/// <value>
/// A <see cref="String"/> providing a comma-delimited list of HTTP verbs supported
/// by the service, <see langword="null"/> or empty if all verbs are supported.
/// A <see cref="String"/> providing a comma-delimited list of HTTP verbs supported
/// by the service, <see langword="null"/> or empty if all verbs are supported.
/// </value>
public string Verbs { get; set; }
/// <summary>
/// Used to rank the precedences of route definitions in reverse routing.
/// Used to rank the precedences of route definitions in reverse routing.
/// i.e. Priorities below 0 are auto-generated have less precedence.
/// </summary>
public int Priority { get; set; }

View file

@ -158,7 +158,7 @@ namespace MediaBrowser.Providers.BoxSets
var dataFilePath = GetDataFilePath(_config.ApplicationPaths, tmdbId, preferredMetadataLanguage);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_json.SerializeToFile(mainResult, dataFilePath);
}

View file

@ -156,7 +156,7 @@ namespace MediaBrowser.Providers.Manager
}).ConfigureAwait(false))
{
// Workaround for tvheadend channel icons
// Workaround for tvheadend channel icons
// TODO: Isolate this hack into the tvh plugin
if (string.IsNullOrEmpty(response.ContentType))
{

View file

@ -70,7 +70,7 @@ namespace MediaBrowser.Providers.Movies
{
return new List<ImageType>
{
ImageType.Primary,
ImageType.Primary,
ImageType.Thumb,
ImageType.Art,
ImageType.Logo,
@ -270,7 +270,7 @@ namespace MediaBrowser.Providers.Movies
var path = GetFanartJsonPath(id);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
try
{

View file

@ -158,7 +158,7 @@ namespace MediaBrowser.Providers.Music
var path = GetAlbumInfoPath(_config.ApplicationPaths, musicBrainzReleaseGroupId);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
using (var httpResponse = await _httpClient.SendAsync(new HttpRequestOptions
{

View file

@ -312,7 +312,7 @@ namespace MediaBrowser.Providers.TV
var path = GetFanartJsonPath(tvdbId);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
try
{

View file

@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.TV
var dataFilePath = GetDataFilePath(id, seasonNumber, episodeNumber, preferredMetadataLanguage);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_jsonSerializer.SerializeToFile(mainResult, dataFilePath);
}

View file

@ -194,7 +194,7 @@ namespace MediaBrowser.Providers.TV
var dataFilePath = GetDataFilePath(id, seasonNumber, preferredMetadataLanguage);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(dataFilePath));
_jsonSerializer.SerializeToFile(mainResult, dataFilePath);
}

View file

@ -58,27 +58,27 @@ namespace MediaBrowser.Providers.TV
// Process images
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds);
var nodes = TvdbEpisodeProvider.Current.GetEpisodeXmlNodes(seriesDataPath, episode.GetLookupInfo());
var nodes = TvdbEpisodeProvider.Current.GetEpisodeXmlNodes(seriesDataPath, episode.GetLookupInfo());
var result = nodes.Select(i => GetImageInfo(i, cancellationToken))
.Where(i => i != null)
.ToList();
.ToList();
return Task.FromResult<IEnumerable<RemoteImageInfo>>(result);
return Task.FromResult<IEnumerable<RemoteImageInfo>>(result);
}
return Task.FromResult<IEnumerable<RemoteImageInfo>>(new RemoteImageInfo[] { });
}
private RemoteImageInfo GetImageInfo(XmlReader reader, CancellationToken cancellationToken)
private RemoteImageInfo GetImageInfo(XmlReader reader, CancellationToken cancellationToken)
{
var height = 225;
var width = 400;
var url = string.Empty;
// Use XmlReader for best performance
using (reader)
{
// Use XmlReader for best performance
using (reader)
{
reader.MoveToContent();
reader.Read();
@ -146,7 +146,7 @@ namespace MediaBrowser.Providers.TV
reader.Read();
}
}
}
}
if (string.IsNullOrEmpty(url))
{

View file

@ -143,7 +143,7 @@ namespace MediaBrowser.Providers.TV
/// <param name="seriesDataPath">The series data path.</param>
/// <param name="searchInfo">The search information.</param>
/// <returns>List{FileInfo}.</returns>
internal List<XmlReader> GetEpisodeXmlNodes(string seriesDataPath, EpisodeInfo searchInfo)
internal List<XmlReader> GetEpisodeXmlNodes(string seriesDataPath, EpisodeInfo searchInfo)
{
var seriesXmlPath = TvdbSeriesProvider.Current.GetSeriesXmlPath(searchInfo.SeriesProviderIds, searchInfo.MetadataLanguage);

View file

@ -38,7 +38,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
return false;
}
return updateType >= MinimumUpdateType || (updateType >= ItemUpdateType.MetadataImport && FileSystem.FileExists(GetSavePath(item)));
return updateType >= MinimumUpdateType || (updateType >= ItemUpdateType.MetadataImport && FileSystem.FileExists(GetSavePath(item)));
}
protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
@ -62,7 +62,15 @@ namespace MediaBrowser.XbmcMetadata.Savers
return list;
}
public SeasonNfoSaver(IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, IUserManager userManager, IUserDataManager userDataManager, ILogger logger, IXmlReaderSettingsFactory xmlReaderSettingsFactory) : base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger, xmlReaderSettingsFactory)
public SeasonNfoSaver(
IFileSystem fileSystem,
IServerConfigurationManager configurationManager,
ILibraryManager libraryManager,
IUserManager userManager,
IUserDataManager userDataManager,
ILogger logger,
IXmlReaderSettingsFactory xmlReaderSettingsFactory)
: base(fileSystem, configurationManager, libraryManager, userManager, userDataManager, logger, xmlReaderSettingsFactory)
{
}
}

View file

@ -13,10 +13,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -34,23 +34,22 @@ using System.Threading.Tasks;
namespace Mono.Nat
{
public abstract class AbstractNatDevice : INatDevice
{
private DateTime lastSeen;
protected AbstractNatDevice ()
{
public abstract class AbstractNatDevice : INatDevice
{
private DateTime lastSeen;
}
protected AbstractNatDevice()
{
}
public abstract IPAddress LocalAddress { get; }
public DateTime LastSeen
{
get { return lastSeen; }
set { lastSeen = value; }
}
public abstract IPAddress LocalAddress { get; }
public abstract Task CreatePortMap(Mapping mapping);
}
public DateTime LastSeen
{
get { return lastSeen; }
set { lastSeen = value; }
}
public abstract Task CreatePortMap(Mapping mapping);
}
}

View file

@ -11,10 +11,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -28,9 +28,9 @@ using System;
namespace Mono.Nat
{
public enum Protocol
{
Tcp,
Udp
}
}
public enum Protocol
{
Tcp,
Udp
}
}

View file

@ -11,10 +11,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -28,18 +28,18 @@ using System;
namespace Mono.Nat
{
public class DeviceEventArgs : EventArgs
{
private INatDevice device;
public DeviceEventArgs(INatDevice device)
{
this.device = device;
}
public INatDevice Device
{
get { return this.device; }
}
}
}
public class DeviceEventArgs : EventArgs
{
private INatDevice device;
public DeviceEventArgs(INatDevice device)
{
this.device = device;
}
public INatDevice Device
{
get { return this.device; }
}
}
}

View file

@ -13,10 +13,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -34,12 +34,12 @@ using System.Threading.Tasks;
namespace Mono.Nat
{
public interface INatDevice
{
Task CreatePortMap (Mapping mapping);
IPAddress LocalAddress { get; }
public interface INatDevice
{
Task CreatePortMap (Mapping mapping);
DateTime LastSeen { get; set; }
}
IPAddress LocalAddress { get; }
DateTime LastSeen { get; set; }
}
}

View file

@ -13,10 +13,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -30,94 +30,92 @@ using System;
namespace Mono.Nat
{
public class Mapping
{
public class Mapping
{
private string description;
private DateTime expiration;
private int lifetime;
private int privatePort;
private Protocol protocol;
private int publicPort;
private Protocol protocol;
private int publicPort;
public Mapping(Protocol protocol, int privatePort, int publicPort)
: this (protocol, privatePort, publicPort, 0)
{
}
public Mapping (Protocol protocol, int privatePort, int publicPort)
: this (protocol, privatePort, publicPort, 0)
{
}
public Mapping (Protocol protocol, int privatePort, int publicPort, int lifetime)
{
this.protocol = protocol;
this.privatePort = privatePort;
this.publicPort = publicPort;
this.lifetime = lifetime;
public Mapping(Protocol protocol, int privatePort, int publicPort, int lifetime)
{
this.protocol = protocol;
this.privatePort = privatePort;
this.publicPort = publicPort;
this.lifetime = lifetime;
if (lifetime == int.MaxValue)
this.expiration = DateTime.MaxValue;
else if (lifetime == 0)
this.expiration = DateTime.Now;
else
this.expiration = DateTime.Now.AddSeconds (lifetime);
}
if (lifetime == int.MaxValue)
this.expiration = DateTime.MaxValue;
else if (lifetime == 0)
this.expiration = DateTime.Now;
else
this.expiration = DateTime.Now.AddSeconds (lifetime);
}
public string Description
{
get { return description; }
set { description = value; }
}
public Protocol Protocol
{
get { return protocol; }
internal set { protocol = value; }
}
public int PrivatePort
{
get { return privatePort; }
internal set { privatePort = value; }
}
public int PublicPort
{
get { return publicPort; }
internal set { publicPort = value; }
}
public int Lifetime
{
get { return lifetime; }
internal set { lifetime = value; }
}
public DateTime Expiration
{
get { return expiration; }
internal set { expiration = value; }
}
public bool IsExpired ()
{
return expiration < DateTime.Now;
}
public override bool Equals (object obj)
{
Mapping other = obj as Mapping;
return other == null ? false : this.protocol == other.protocol &&
this.privatePort == other.privatePort && this.publicPort == other.publicPort;
}
public override int GetHashCode()
{
return this.protocol.GetHashCode() ^ this.privatePort.GetHashCode() ^ this.publicPort.GetHashCode();
}
public override string ToString( )
public Protocol Protocol
{
return String.Format( "Protocol: {0}, Public Port: {1}, Private Port: {2}, Description: {3}, Expiration: {4}, Lifetime: {5}",
this.protocol, this.publicPort, this.privatePort, this.description, this.expiration, this.lifetime );
get { return protocol; }
internal set { protocol = value; }
}
}
public int PrivatePort
{
get { return privatePort; }
internal set { privatePort = value; }
}
public int PublicPort
{
get { return publicPort; }
internal set { publicPort = value; }
}
public int Lifetime
{
get { return lifetime; }
internal set { lifetime = value; }
}
public DateTime Expiration
{
get { return expiration; }
internal set { expiration = value; }
}
public bool IsExpired()
{
return expiration < DateTime.Now;
}
public override bool Equals(object obj)
{
Mapping other = obj as Mapping;
return other == null ? false : this.protocol == other.protocol &&
this.privatePort == other.privatePort && this.publicPort == other.publicPort;
}
public override int GetHashCode()
{
return this.protocol.GetHashCode() ^ this.privatePort.GetHashCode() ^ this.publicPort.GetHashCode();
}
public override string ToString()
{
return String.Format( "Protocol: {0}, Public Port: {1}, Private Port: {2}, Description: {3}, Expiration: {4}, Lifetime: {5}",
this.protocol, this.publicPort, this.privatePort, this.description, this.expiration, this.lifetime );
}
}
}

View file

@ -11,10 +11,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -29,28 +29,28 @@ using System;
namespace Mono.Nat.Pmp
{
internal static class PmpConstants
{
public const byte Version = (byte)0;
public const byte OperationCode = (byte)0;
public const byte OperationCodeUdp = (byte)1;
public const byte OperationCodeTcp = (byte)2;
{
public const byte Version = (byte)0;
public const byte OperationCode = (byte)0;
public const byte OperationCodeUdp = (byte)1;
public const byte OperationCodeTcp = (byte)2;
public const byte ServerNoop = (byte)128;
public const int ClientPort = 5350;
public const int ServerPort = 5351;
public const int RetryDelay = 250;
public const int RetryAttempts = 9;
public const int RecommendedLeaseTime = 60 * 60;
public const int DefaultLeaseTime = RecommendedLeaseTime;
public const short ResultCodeSuccess = 0;
public const short ResultCodeUnsupportedVersion = 1;
public const short ResultCodeNotAuthorized = 2;
public const short ResultCodeNetworkFailure = 3;
public const short ResultCodeOutOfResources = 4;
public const short ResultCodeUnsupportedOperationCode = 5;
}
}
public const int ClientPort = 5350;
public const int ServerPort = 5351;
public const int RetryDelay = 250;
public const int RetryAttempts = 9;
public const int RecommendedLeaseTime = 60 * 60;
public const int DefaultLeaseTime = RecommendedLeaseTime;
public const short ResultCodeSuccess = 0;
public const short ResultCodeUnsupportedVersion = 1;
public const short ResultCodeNotAuthorized = 2;
public const short ResultCodeNetworkFailure = 3;
public const short ResultCodeOutOfResources = 4;
public const short ResultCodeUnsupportedOperationCode = 5;
}
}

View file

@ -15,10 +15,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -108,8 +108,8 @@ namespace Mono.Nat
foreach (var unicast in properties.UnicastAddresses)
{
if (/*unicast.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
&& unicast.AddressPreferredLifetime != UInt32.MaxValue
&& */unicast.Address.AddressFamily == AddressFamily.InterNetwork)
&& unicast.AddressPreferredLifetime != UInt32.MaxValue
&& */unicast.Address.AddressFamily == AddressFamily.InterNetwork)
{
var bytes = unicast.Address.GetAddressBytes();
bytes[3] = 1;
@ -165,7 +165,7 @@ namespace Mono.Nat
async Task Search(UdpClient client)
{
// Sort out the time for the next search first. The spec says the
// Sort out the time for the next search first. The spec says the
// timeout should double after each attempt. Once it reaches 64 seconds
// (and that attempt fails), assume no devices available
nextSearch = DateTime.Now.AddMilliseconds(timeout);

View file

@ -15,10 +15,10 @@
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@ -58,8 +58,8 @@ namespace Mono.Nat
}
public void Search()
{
}
{
}
public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
{
@ -70,16 +70,16 @@ namespace Mono.Nat
try
{
/* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
Any other device type is no good to us for this purpose. See the IGP overview paper
page 5 for an overview of device types and their hierarchy.
http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */
/* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
* Any other device type is no good to us for this purpose. See the IGP overview paper
* page 5 for an overview of device types and their hierarchy.
* http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */
/* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
version it is and apply the correct URN. */
* version it is and apply the correct URN. */
/* Some routers don't correctly implement the version ID on the URN, so we only search for the type
prefix. */
* prefix. */
// We have an internet gateway device now
UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient);

View file

@ -47,7 +47,7 @@ namespace OpenSubtitlesHandler
/// <returns>The hash as Hexadecimal string</returns>
public static string ComputeHash(Stream stream)
{
byte[] hash = MovieHasher.ComputeMovieHash(stream);
byte[] hash = MovieHasher.ComputeMovieHash(stream);
return MovieHasher.ToHexadecimal(hash);
}
/// <summary>

View file

@ -6,57 +6,56 @@ using MediaBrowser.Model.Net;
namespace Rssdp
{
/// <summary>
/// Event arguments for the <see cref="Rssdp.Infrastructure.SsdpDeviceLocatorBase.DeviceAvailable"/> event.
/// </summary>
public sealed class DeviceAvailableEventArgs : EventArgs
{
/// <summary>
/// Event arguments for the <see cref="Rssdp.Infrastructure.SsdpDeviceLocatorBase.DeviceAvailable"/> event.
/// </summary>
public sealed class DeviceAvailableEventArgs : EventArgs
{
public IpAddressInfo LocalIpAddress { get; set; }
#region Fields
private readonly DiscoveredSsdpDevice _DiscoveredDevice;
private readonly bool _IsNewlyDiscovered;
private readonly bool _IsNewlyDiscovered;
#endregion
#endregion
#region Constructors
#region Constructors
/// <summary>
/// Full constructor.
/// </summary>
/// <param name="discoveredDevice">A <see cref="DiscoveredSsdpDevice"/> instance representing the available device.</param>
/// <param name="isNewlyDiscovered">A boolean value indicating whether or not this device came from the cache. See <see cref="IsNewlyDiscovered"/> for more detail.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="discoveredDevice"/> parameter is null.</exception>
public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered)
{
if (discoveredDevice == null) throw new ArgumentNullException("discoveredDevice");
/// <summary>
/// Full constructor.
/// </summary>
/// <param name="discoveredDevice">A <see cref="DiscoveredSsdpDevice"/> instance representing the available device.</param>
/// <param name="isNewlyDiscovered">A boolean value indicating whether or not this device came from the cache. See <see cref="IsNewlyDiscovered"/> for more detail.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="discoveredDevice"/> parameter is null.</exception>
public DeviceAvailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool isNewlyDiscovered)
{
if (discoveredDevice == null) throw new ArgumentNullException("discoveredDevice");
_DiscoveredDevice = discoveredDevice;
_IsNewlyDiscovered = isNewlyDiscovered;
}
_DiscoveredDevice = discoveredDevice;
_IsNewlyDiscovered = isNewlyDiscovered;
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Returns true if the device was discovered due to an alive notification, or a search and was not already in the cache. Returns false if the item came from the cache but matched the current search request.
/// </summary>
public bool IsNewlyDiscovered
{
get { return _IsNewlyDiscovered; }
}
/// <summary>
/// Returns true if the device was discovered due to an alive notification, or a search and was not already in the cache. Returns false if the item came from the cache but matched the current search request.
/// </summary>
public bool IsNewlyDiscovered
{
get { return _IsNewlyDiscovered; }
}
/// <summary>
/// A reference to a <see cref="Rssdp.DiscoveredSsdpDevice"/> instance containing the discovered details and allowing access to the full device description.
/// </summary>
public DiscoveredSsdpDevice DiscoveredDevice
{
get { return _DiscoveredDevice; }
}
/// <summary>
/// A reference to a <see cref="Rssdp.DiscoveredSsdpDevice"/> instance containing the discovered details and allowing access to the full device description.
/// </summary>
public DiscoveredSsdpDevice DiscoveredDevice
{
get { return _DiscoveredDevice; }
}
#endregion
}
}
#endregion
}
}

View file

@ -4,45 +4,45 @@ using System.Text;
namespace Rssdp
{
/// <summary>
/// Event arguments for the <see cref="SsdpDevice.DeviceAdded"/> and <see cref="SsdpDevice.DeviceRemoved"/> events.
/// </summary>
public sealed class DeviceEventArgs : EventArgs
{
/// <summary>
/// Event arguments for the <see cref="SsdpDevice.DeviceAdded"/> and <see cref="SsdpDevice.DeviceRemoved"/> events.
/// </summary>
public sealed class DeviceEventArgs : EventArgs
{
#region Fields
#region Fields
private readonly SsdpDevice _Device;
private readonly SsdpDevice _Device;
#endregion
#endregion
#region Constructors
#region Constructors
/// <summary>
/// Constructs a new instance for the specified <see cref="SsdpDevice"/>.
/// </summary>
/// <param name="device">The <see cref="SsdpDevice"/> associated with the event this argument class is being used for.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="device"/> argument is null.</exception>
public DeviceEventArgs(SsdpDevice device)
{
if (device == null) throw new ArgumentNullException("device");
/// <summary>
/// Constructs a new instance for the specified <see cref="SsdpDevice"/>.
/// </summary>
/// <param name="device">The <see cref="SsdpDevice"/> associated with the event this argument class is being used for.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="device"/> argument is null.</exception>
public DeviceEventArgs(SsdpDevice device)
{
if (device == null) throw new ArgumentNullException("device");
_Device = device;
}
_Device = device;
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Returns the <see cref="SsdpDevice"/> instance the event being raised for.
/// </summary>
public SsdpDevice Device
{
get { return _Device; }
}
/// <summary>
/// Returns the <see cref="SsdpDevice"/> instance the event being raised for.
/// </summary>
public SsdpDevice Device
{
get { return _Device; }
}
#endregion
#endregion
}
}
}
}

View file

@ -5,55 +5,55 @@ using System.Threading.Tasks;
namespace Rssdp
{
/// <summary>
/// Event arguments for the <see cref="Rssdp.Infrastructure.SsdpDeviceLocatorBase.DeviceUnavailable"/> event.
/// </summary>
public sealed class DeviceUnavailableEventArgs : EventArgs
{
/// <summary>
/// Event arguments for the <see cref="Rssdp.Infrastructure.SsdpDeviceLocatorBase.DeviceUnavailable"/> event.
/// </summary>
public sealed class DeviceUnavailableEventArgs : EventArgs
{
#region Fields
#region Fields
private readonly DiscoveredSsdpDevice _DiscoveredDevice;
private readonly bool _Expired;
private readonly DiscoveredSsdpDevice _DiscoveredDevice;
private readonly bool _Expired;
#endregion
#endregion
#region Constructors
#region Constructors
/// <summary>
/// Full constructor.
/// </summary>
/// <param name="discoveredDevice">A <see cref="DiscoveredSsdpDevice"/> instance representing the device that has become unavailable.</param>
/// <param name="expired">A boolean value indicating whether this device is unavailable because it expired, or because it explicitly sent a byebye notification.. See <see cref="Expired"/> for more detail.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="discoveredDevice"/> parameter is null.</exception>
public DeviceUnavailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool expired)
{
if (discoveredDevice == null) throw new ArgumentNullException("discoveredDevice");
/// <summary>
/// Full constructor.
/// </summary>
/// <param name="discoveredDevice">A <see cref="DiscoveredSsdpDevice"/> instance representing the device that has become unavailable.</param>
/// <param name="expired">A boolean value indicating whether this device is unavailable because it expired, or because it explicitly sent a byebye notification.. See <see cref="Expired"/> for more detail.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <paramref name="discoveredDevice"/> parameter is null.</exception>
public DeviceUnavailableEventArgs(DiscoveredSsdpDevice discoveredDevice, bool expired)
{
if (discoveredDevice == null) throw new ArgumentNullException("discoveredDevice");
_DiscoveredDevice = discoveredDevice;
_Expired = expired;
}
_DiscoveredDevice = discoveredDevice;
_Expired = expired;
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Returns true if the device is considered unavailable because it's cached information expired before a new alive notification or search result was received. Returns false if the device is unavailable because it sent an explicit notification of it's unavailability.
/// </summary>
public bool Expired
{
get { return _Expired; }
}
/// <summary>
/// Returns true if the device is considered unavailable because it's cached information expired before a new alive notification or search result was received. Returns false if the device is unavailable because it sent an explicit notification of it's unavailability.
/// </summary>
public bool Expired
{
get { return _Expired; }
}
/// <summary>
/// A reference to a <see cref="Rssdp.DiscoveredSsdpDevice"/> instance containing the discovery details of the removed device.
/// </summary>
public DiscoveredSsdpDevice DiscoveredDevice
{
get { return _DiscoveredDevice; }
}
/// <summary>
/// A reference to a <see cref="Rssdp.DiscoveredSsdpDevice"/> instance containing the discovery details of the removed device.
/// </summary>
public DiscoveredSsdpDevice DiscoveredDevice
{
get { return _DiscoveredDevice; }
}
#endregion
}
}
#endregion
}
}

View file

@ -7,88 +7,88 @@ using System.Net.Http.Headers;
namespace Rssdp
{
/// <summary>
/// Represents a discovered device, containing basic information about the device and the location of it's full device description document. Also provides convenience methods for retrieving the device description document.
/// </summary>
/// <seealso cref="SsdpDevice"/>
/// <seealso cref="Rssdp.Infrastructure.ISsdpDeviceLocator"/>
public sealed class DiscoveredSsdpDevice
{
/// <summary>
/// Represents a discovered device, containing basic information about the device and the location of it's full device description document. Also provides convenience methods for retrieving the device description document.
/// </summary>
/// <seealso cref="SsdpDevice"/>
/// <seealso cref="Rssdp.Infrastructure.ISsdpDeviceLocator"/>
public sealed class DiscoveredSsdpDevice
{
#region Fields
#region Fields
private DateTimeOffset _AsAt;
private DateTimeOffset _AsAt;
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Sets or returns the type of notification, being either a uuid, device type, service type or upnp:rootdevice.
/// </summary>
public string NotificationType { get; set; }
/// <summary>
/// Sets or returns the type of notification, being either a uuid, device type, service type or upnp:rootdevice.
/// </summary>
public string NotificationType { get; set; }
/// <summary>
/// Sets or returns the universal service name (USN) of the device.
/// </summary>
public string Usn { get; set; }
/// <summary>
/// Sets or returns the universal service name (USN) of the device.
/// </summary>
public string Usn { get; set; }
/// <summary>
/// Sets or returns a URL pointing to the device description document for this device.
/// </summary>
public Uri DescriptionLocation { get; set; }
/// <summary>
/// Sets or returns a URL pointing to the device description document for this device.
/// </summary>
public Uri DescriptionLocation { get; set; }
/// <summary>
/// Sets or returns the length of time this information is valid for (from the <see cref="AsAt"/> time).
/// </summary>
public TimeSpan CacheLifetime { get; set; }
/// <summary>
/// Sets or returns the length of time this information is valid for (from the <see cref="AsAt"/> time).
/// </summary>
public TimeSpan CacheLifetime { get; set; }
/// <summary>
/// Sets or returns the date and time this information was received.
/// </summary>
public DateTimeOffset AsAt
{
get { return _AsAt; }
set
{
if (_AsAt != value)
{
_AsAt = value;
}
}
}
/// <summary>
/// Sets or returns the date and time this information was received.
/// </summary>
public DateTimeOffset AsAt
{
get { return _AsAt; }
set
{
if (_AsAt != value)
{
_AsAt = value;
}
}
}
/// <summary>
/// Returns the headers from the SSDP device response message
/// </summary>
public HttpHeaders ResponseHeaders { get; set; }
/// <summary>
/// Returns the headers from the SSDP device response message
/// </summary>
public HttpHeaders ResponseHeaders { get; set; }
#endregion
#endregion
#region Public Methods
#region Public Methods
/// <summary>
/// Returns true if this device information has expired, based on the current date/time, and the <see cref="CacheLifetime"/> &amp; <see cref="AsAt"/> properties.
/// </summary>
/// <returns></returns>
public bool IsExpired()
{
return this.CacheLifetime == TimeSpan.Zero || this.AsAt.Add(this.CacheLifetime) <= DateTimeOffset.Now;
}
/// <summary>
/// Returns true if this device information has expired, based on the current date/time, and the <see cref="CacheLifetime"/> &amp; <see cref="AsAt"/> properties.
/// </summary>
/// <returns></returns>
public bool IsExpired()
{
return this.CacheLifetime == TimeSpan.Zero || this.AsAt.Add(this.CacheLifetime) <= DateTimeOffset.Now;
}
#endregion
#endregion
#region Overrides
#region Overrides
/// <summary>
/// Returns the device's <see cref="Usn"/> value.
/// </summary>
/// <returns>A string containing the device's universal service name.</returns>
public override string ToString()
{
return this.Usn;
}
/// <summary>
/// Returns the device's <see cref="Usn"/> value.
/// </summary>
/// <returns>A string containing the device's universal service name.</returns>
public override string ToString()
{
return this.Usn;
}
#endregion
}
#endregion
}
}

View file

@ -5,44 +5,44 @@ using System.Threading.Tasks;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Correclty implements the <see cref="IDisposable"/> interface and pattern for an object containing only managed resources, and adds a few common niceities not on the interface such as an <see cref="IsDisposed"/> property.
/// </summary>
public abstract class DisposableManagedObjectBase : IDisposable
{
/// <summary>
/// Correclty implements the <see cref="IDisposable"/> interface and pattern for an object containing only managed resources, and adds a few common niceities not on the interface such as an <see cref="IsDisposed"/> property.
/// </summary>
public abstract class DisposableManagedObjectBase : IDisposable
{
#region Public Methods
#region Public Methods
/// <summary>
/// Override this method and dispose any objects you own the lifetime of if disposing is true;
/// </summary>
/// <param name="disposing">True if managed objects should be disposed, if false, only unmanaged resources should be released.</param>
protected abstract void Dispose(bool disposing);
/// <summary>
/// Override this method and dispose any objects you own the lifetime of if disposing is true;
/// </summary>
/// <param name="disposing">True if managed objects should be disposed, if false, only unmanaged resources should be released.</param>
protected abstract void Dispose(bool disposing);
/// <summary>
/// Throws and <see cref="System.ObjectDisposedException"/> if the <see cref="IsDisposed"/> property is true.
/// </summary>
/// <seealso cref="IsDisposed"/>
/// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="IsDisposed"/> property is true.</exception>
/// <seealso cref="Dispose()"/>
protected virtual void ThrowIfDisposed()
{
if (this.IsDisposed) throw new ObjectDisposedException(this.GetType().FullName);
}
/// <summary>
/// Throws and <see cref="System.ObjectDisposedException"/> if the <see cref="IsDisposed"/> property is true.
/// </summary>
/// <seealso cref="IsDisposed"/>
/// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="IsDisposed"/> property is true.</exception>
/// <seealso cref="Dispose()"/>
protected virtual void ThrowIfDisposed()
{
if (this.IsDisposed) throw new ObjectDisposedException(this.GetType().FullName);
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Sets or returns a boolean indicating whether or not this instance has been disposed.
/// </summary>
/// <seealso cref="Dispose()"/>
public bool IsDisposed
{
get;
private set;
}
/// <summary>
/// Sets or returns a boolean indicating whether or not this instance has been disposed.
/// </summary>
/// <seealso cref="Dispose()"/>
public bool IsDisposed
{
get;
private set;
}
#endregion
@ -63,7 +63,7 @@ namespace Rssdp.Infrastructure
return builder.ToString();
}
#region IDisposable Members
/// <summary>
@ -74,8 +74,8 @@ namespace Rssdp.Infrastructure
/// </remarks>
/// <seealso cref="IsDisposed"/>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification="We do exactly as asked, but CA doesn't seem to like us also setting the IsDisposed property. Too bad, it's a good idea and shouldn't cause an exception or anything likely to interfer with the dispose process.")]
public void Dispose()
{
public void Dispose()
{
IsDisposed = true;
Dispose(true);
@ -83,4 +83,4 @@ namespace Rssdp.Infrastructure
#endregion
}
}
}

View file

@ -8,70 +8,70 @@ using System.Threading.Tasks;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Parses a string into a <see cref="System.Net.Http.HttpRequestMessage"/> or throws an exception.
/// </summary>
public sealed class HttpRequestParser : HttpParserBase<HttpRequestMessage>
{
/// <summary>
/// Parses a string into a <see cref="System.Net.Http.HttpRequestMessage"/> or throws an exception.
/// </summary>
public sealed class HttpRequestParser : HttpParserBase<HttpRequestMessage>
{
#region Fields & Constants
#region Fields & Constants
private readonly string[] ContentHeaderNames = new string[]
{
"Allow", "Content-Disposition", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified"
};
private readonly string[] ContentHeaderNames = new string[]
{
"Allow", "Content-Disposition", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified"
};
#endregion
#endregion
#region Public Methods
#region Public Methods
/// <summary>
/// Parses the specified data into a <see cref="System.Net.Http.HttpRequestMessage"/> instance.
/// </summary>
/// <param name="data">A string containing the data to parse.</param>
/// <returns>A <see cref="System.Net.Http.HttpRequestMessage"/> instance containing the parsed data.</returns>
public override System.Net.Http.HttpRequestMessage Parse(string data)
{
System.Net.Http.HttpRequestMessage retVal = null;
/// <summary>
/// Parses the specified data into a <see cref="System.Net.Http.HttpRequestMessage"/> instance.
/// </summary>
/// <param name="data">A string containing the data to parse.</param>
/// <returns>A <see cref="System.Net.Http.HttpRequestMessage"/> instance containing the parsed data.</returns>
public override System.Net.Http.HttpRequestMessage Parse(string data)
{
System.Net.Http.HttpRequestMessage retVal = null;
try
{
retVal = new System.Net.Http.HttpRequestMessage();
try
{
retVal = new System.Net.Http.HttpRequestMessage();
Parse(retVal, retVal.Headers, data);
Parse(retVal, retVal.Headers, data);
return retVal;
}
finally
{
if (retVal != null)
retVal.Dispose();
}
}
return retVal;
}
finally
{
if (retVal != null)
retVal.Dispose();
}
}
#endregion
#endregion
#region Overrides
#region Overrides
/// <summary>
/// Used to parse the first line of an HTTP request or response and assign the values to the appropriate properties on the <paramref name="message"/>.
/// </summary>
/// <param name="data">The first line of the HTTP message to be parsed.</param>
/// <param name="message">Either a <see cref="System.Net.Http.HttpResponseMessage"/> or <see cref="System.Net.Http.HttpRequestMessage"/> to assign the parsed values to.</param>
protected override void ParseStatusLine(string data, HttpRequestMessage message)
{
if (data == null) throw new ArgumentNullException("data");
if (message == null) throw new ArgumentNullException("message");
/// <summary>
/// Used to parse the first line of an HTTP request or response and assign the values to the appropriate properties on the <paramref name="message"/>.
/// </summary>
/// <param name="data">The first line of the HTTP message to be parsed.</param>
/// <param name="message">Either a <see cref="System.Net.Http.HttpResponseMessage"/> or <see cref="System.Net.Http.HttpRequestMessage"/> to assign the parsed values to.</param>
protected override void ParseStatusLine(string data, HttpRequestMessage message)
{
if (data == null) throw new ArgumentNullException("data");
if (message == null) throw new ArgumentNullException("message");
var parts = data.Split(' ');
if (parts.Length < 2) throw new ArgumentException("Status line is invalid. Insufficient status parts.", "data");
var parts = data.Split(' ');
if (parts.Length < 2) throw new ArgumentException("Status line is invalid. Insufficient status parts.", "data");
message.Method = new HttpMethod(parts[0].Trim());
Uri requestUri;
if (Uri.TryCreate(parts[1].Trim(), UriKind.RelativeOrAbsolute, out requestUri))
message.RequestUri = requestUri;
else
System.Diagnostics.Debug.WriteLine(parts[1]);
message.Method = new HttpMethod(parts[0].Trim());
Uri requestUri;
if (Uri.TryCreate(parts[1].Trim(), UriKind.RelativeOrAbsolute, out requestUri))
message.RequestUri = requestUri;
else
System.Diagnostics.Debug.WriteLine(parts[1]);
if (parts.Length >= 3)
{
@ -79,16 +79,16 @@ namespace Rssdp.Infrastructure
}
}
/// <summary>
/// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false).
/// </summary>
/// <param name="headerName">A string containing the name of the header to return the type of.</param>
protected override bool IsContentHeader(string headerName)
{
return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false).
/// </summary>
/// <param name="headerName">A string containing the name of the header to return the type of.</param>
protected override bool IsContentHeader(string headerName)
{
return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase);
}
#endregion
#endregion
}
}
}
}

View file

@ -8,82 +8,82 @@ using System.Threading.Tasks;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Parses a string into a <see cref="System.Net.Http.HttpResponseMessage"/> or throws an exception.
/// </summary>
public sealed class HttpResponseParser : HttpParserBase<System.Net.Http.HttpResponseMessage>
{
/// <summary>
/// Parses a string into a <see cref="System.Net.Http.HttpResponseMessage"/> or throws an exception.
/// </summary>
public sealed class HttpResponseParser : HttpParserBase<System.Net.Http.HttpResponseMessage>
{
#region Fields & Constants
#region Fields & Constants
private readonly string[] ContentHeaderNames = new string[]
{
"Allow", "Content-Disposition", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified"
};
private readonly string[] ContentHeaderNames = new string[]
{
"Allow", "Content-Disposition", "Content-Encoding", "Content-Language", "Content-Length", "Content-Location", "Content-MD5", "Content-Range", "Content-Type", "Expires", "Last-Modified"
};
#endregion
#endregion
#region Public Methods
#region Public Methods
/// <summary>
/// Parses the specified data into a <see cref="System.Net.Http.HttpResponseMessage"/> instance.
/// </summary>
/// <param name="data">A string containing the data to parse.</param>
/// <returns>A <see cref="System.Net.Http.HttpResponseMessage"/> instance containing the parsed data.</returns>
public override HttpResponseMessage Parse(string data)
{
System.Net.Http.HttpResponseMessage retVal = null;
try
{
retVal = new System.Net.Http.HttpResponseMessage();
/// <summary>
/// Parses the specified data into a <see cref="System.Net.Http.HttpResponseMessage"/> instance.
/// </summary>
/// <param name="data">A string containing the data to parse.</param>
/// <returns>A <see cref="System.Net.Http.HttpResponseMessage"/> instance containing the parsed data.</returns>
public override HttpResponseMessage Parse(string data)
{
System.Net.Http.HttpResponseMessage retVal = null;
try
{
retVal = new System.Net.Http.HttpResponseMessage();
Parse(retVal, retVal.Headers, data);
Parse(retVal, retVal.Headers, data);
return retVal;
}
catch
{
if (retVal != null)
retVal.Dispose();
return retVal;
}
catch
{
if (retVal != null)
retVal.Dispose();
throw;
}
}
throw;
}
}
#endregion
#endregion
#region Overrides Methods
#region Overrides Methods
/// <summary>
/// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false).
/// </summary>
/// <param name="headerName">A string containing the name of the header to return the type of.</param>
/// <returns>A boolean, true if th specified header relates to HTTP content, otherwise false.</returns>
protected override bool IsContentHeader(string headerName)
{
return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false).
/// </summary>
/// <param name="headerName">A string containing the name of the header to return the type of.</param>
/// <returns>A boolean, true if th specified header relates to HTTP content, otherwise false.</returns>
protected override bool IsContentHeader(string headerName)
{
return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase);
}
/// <summary>
/// Used to parse the first line of an HTTP request or response and assign the values to the appropriate properties on the <paramref name="message"/>.
/// </summary>
/// <param name="data">The first line of the HTTP message to be parsed.</param>
/// <param name="message">Either a <see cref="System.Net.Http.HttpResponseMessage"/> or <see cref="System.Net.Http.HttpRequestMessage"/> to assign the parsed values to.</param>
protected override void ParseStatusLine(string data, HttpResponseMessage message)
{
if (data == null) throw new ArgumentNullException("data");
if (message == null) throw new ArgumentNullException("message");
/// <summary>
/// Used to parse the first line of an HTTP request or response and assign the values to the appropriate properties on the <paramref name="message"/>.
/// </summary>
/// <param name="data">The first line of the HTTP message to be parsed.</param>
/// <param name="message">Either a <see cref="System.Net.Http.HttpResponseMessage"/> or <see cref="System.Net.Http.HttpRequestMessage"/> to assign the parsed values to.</param>
protected override void ParseStatusLine(string data, HttpResponseMessage message)
{
if (data == null) throw new ArgumentNullException("data");
if (message == null) throw new ArgumentNullException("message");
var parts = data.Split(' ');
if (parts.Length < 2) throw new ArgumentException("data status line is invalid. Insufficient status parts.", "data");
var parts = data.Split(' ');
if (parts.Length < 2) throw new ArgumentException("data status line is invalid. Insufficient status parts.", "data");
message.Version = ParseHttpVersion(parts[0].Trim());
message.Version = ParseHttpVersion(parts[0].Trim());
int statusCode = -1;
if (!Int32.TryParse(parts[1].Trim(), out statusCode))
throw new ArgumentException("data status line is invalid. Status code is not a valid integer.", "data");
int statusCode = -1;
if (!Int32.TryParse(parts[1].Trim(), out statusCode))
throw new ArgumentException("data status line is invalid. Status code is not a valid integer.", "data");
message.StatusCode = (HttpStatusCode)statusCode;
message.StatusCode = (HttpStatusCode)statusCode;
if (parts.Length >= 3)
{
@ -91,7 +91,6 @@ namespace Rssdp.Infrastructure
}
}
#endregion
}
}
#endregion
}
}

View file

@ -5,24 +5,24 @@ using System.Text;
namespace Rssdp.Infrastructure
{
internal static class IEnumerableExtensions
{
public static IEnumerable<T> SelectManyRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
{
if (source == null) throw new ArgumentNullException("source");
if (selector == null) throw new ArgumentNullException("selector");
internal static class IEnumerableExtensions
{
public static IEnumerable<T> SelectManyRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
{
if (source == null) throw new ArgumentNullException("source");
if (selector == null) throw new ArgumentNullException("selector");
return !source.Any() ? source :
source.Concat(
source
.SelectMany(i => selector(i).EmptyIfNull())
.SelectManyRecursive(selector)
);
}
return !source.Any() ? source :
source.Concat(
source
.SelectMany(i => selector(i).EmptyIfNull())
.SelectManyRecursive(selector)
);
}
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
}
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
}
}

View file

@ -2,140 +2,140 @@
namespace Rssdp.Infrastructure
{
/// <summary>
/// Interface for components that discover the existence of SSDP devices.
/// </summary>
/// <remarks>
/// <para>Discovering devices includes explicit search requests as well as listening for broadcast status notifications.</para>
/// </remarks>
/// <seealso cref="DiscoveredSsdpDevice"/>
/// <seealso cref="SsdpDevice"/>
/// <seealso cref="ISsdpDevicePublisher"/>
public interface ISsdpDeviceLocator
{
/// <summary>
/// Interface for components that discover the existence of SSDP devices.
/// </summary>
/// <remarks>
/// <para>Discovering devices includes explicit search requests as well as listening for broadcast status notifications.</para>
/// </remarks>
/// <seealso cref="DiscoveredSsdpDevice"/>
/// <seealso cref="SsdpDevice"/>
/// <seealso cref="ISsdpDevicePublisher"/>
public interface ISsdpDeviceLocator
{
#region Events
#region Events
/// <summary>
/// Event raised when a device becomes available or is found by a search request.
/// </summary>
/// <seealso cref="NotificationFilter"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/>
event EventHandler<DeviceAvailableEventArgs> DeviceAvailable;
/// <summary>
/// Event raised when a device explicitly notifies of shutdown or a device expires from the cache.
/// </summary>
/// <seeseealso cref="NotificationFilter"/>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/>
event EventHandler<DeviceUnavailableEventArgs> DeviceUnavailable;
/// <summary>
/// Event raised when a device becomes available or is found by a search request.
/// </summary>
/// <seealso cref="NotificationFilter"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/>
event EventHandler<DeviceAvailableEventArgs> DeviceAvailable;
#endregion
/// <summary>
/// Event raised when a device explicitly notifies of shutdown or a device expires from the cache.
/// </summary>
/// <seeseealso cref="NotificationFilter"/>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/>
event EventHandler<DeviceUnavailableEventArgs> DeviceUnavailable;
#region Properties
#endregion
/// <summary>
/// Sets or returns a string containing the filter for notifications. Notifications not matching the filter will not raise the <see cref="DeviceAvailable"/> or <see cref="DeviceUnavailable"/> events.
/// </summary>
/// <remarks>
/// <para>Device alive/byebye notifications whose NT header does not match this filter value will still be captured and cached internally, but will not raise events about device availability. Usually used with either a device type of uuid NT header value.</para>
/// <para>Example filters follow;</para>
/// <example>upnp:rootdevice</example>
/// <example>urn:schemas-upnp-org:device:WANDevice:1</example>
/// <example>"uuid:9F15356CC-95FA-572E-0E99-85B456BD3012"</example>
/// </remarks>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/>
string NotificationFilter
{
get;
set;
}
#region Properties
#endregion
/// <summary>
/// Sets or returns a string containing the filter for notifications. Notifications not matching the filter will not raise the <see cref="DeviceAvailable"/> or <see cref="DeviceUnavailable"/> events.
/// </summary>
/// <remarks>
/// <para>Device alive/byebye notifications whose NT header does not match this filter value will still be captured and cached internally, but will not raise events about device availability. Usually used with either a device type of uuid NT header value.</para>
/// <para>Example filters follow;</para>
/// <example>upnp:rootdevice</example>
/// <example>urn:schemas-upnp-org:device:WANDevice:1</example>
/// <example>"uuid:9F15356CC-95FA-572E-0E99-85B456BD3012"</example>
/// </remarks>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/>
string NotificationFilter
{
get;
set;
}
#region Methods
#endregion
#region SearchAsync Overloads
#region Methods
/// <summary>
/// Aynchronously performs a search for all devices using the default search timeout, and returns an awaitable task that can be used to retrieve the results.
/// </summary>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync();
#region SearchAsync Overloads
/// <summary>
/// Performs a search for the specified search target (criteria) and default search timeout.
/// </summary>
/// <param name="searchTarget">The criteria for the search. Value can be;
/// <list type="table">
/// <item><term>Root devices</term><description>upnp:rootdevice</description></item>
/// <item><term>Specific device by UUID</term><description>uuid:&lt;device uuid&gt;</description></item>
/// <item><term>Device type</term><description>Fully qualified device type starting with urn: i.e urn:schemas-upnp-org:Basic:1</description></item>
/// </list>
/// </param>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(string searchTarget);
/// <summary>
/// Aynchronously performs a search for all devices using the default search timeout, and returns an awaitable task that can be used to retrieve the results.
/// </summary>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync();
/// <summary>
/// Performs a search for the specified search target (criteria) and search timeout.
/// </summary>
/// <param name="searchTarget">The criteria for the search. Value can be;
/// <list type="table">
/// <item><term>Root devices</term><description>upnp:rootdevice</description></item>
/// <item><term>Specific device by UUID</term><description>uuid:&lt;device uuid&gt;</description></item>
/// <item><term>Device type</term><description>A device namespace and type in format of urn:&lt;device namespace&gt;:device:&lt;device type&gt;:&lt;device version&gt; i.e urn:schemas-upnp-org:device:Basic:1</description></item>
/// <item><term>Service type</term><description>A service namespace and type in format of urn:&lt;service namespace&gt;:service:&lt;servicetype&gt;:&lt;service version&gt; i.e urn:my-namespace:service:MyCustomService:1</description></item>
/// </list>
/// </param>
/// <param name="searchWaitTime">The amount of time to wait for network responses to the search request. Longer values will likely return more devices, but increase search time. A value between 1 and 5 is recommended by the UPnP 1.1 specification. Specify TimeSpan.Zero to return only devices already in the cache.</param>
/// <remarks>
/// <para>By design RSSDP does not support 'publishing services' as it is intended for use with non-standard UPnP devices that don't publish UPnP style services. However, it is still possible to use RSSDP to search for devices implemetning these services if you know the service type.</para>
/// </remarks>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(string searchTarget, TimeSpan searchWaitTime);
/// <summary>
/// Performs a search for the specified search target (criteria) and default search timeout.
/// </summary>
/// <param name="searchTarget">The criteria for the search. Value can be;
/// <list type="table">
/// <item><term>Root devices</term><description>upnp:rootdevice</description></item>
/// <item><term>Specific device by UUID</term><description>uuid:&lt;device uuid&gt;</description></item>
/// <item><term>Device type</term><description>Fully qualified device type starting with urn: i.e urn:schemas-upnp-org:Basic:1</description></item>
/// </list>
/// </param>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(string searchTarget);
/// <summary>
/// Performs a search for all devices using the specified search timeout.
/// </summary>
/// <param name="searchWaitTime">The amount of time to wait for network responses to the search request. Longer values will likely return more devices, but increase search time. A value between 1 and 5 is recommended by the UPnP 1.1 specification. Specify TimeSpan.Zero to return only devices already in the cache.</param>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(TimeSpan searchWaitTime);
/// <summary>
/// Performs a search for the specified search target (criteria) and search timeout.
/// </summary>
/// <param name="searchTarget">The criteria for the search. Value can be;
/// <list type="table">
/// <item><term>Root devices</term><description>upnp:rootdevice</description></item>
/// <item><term>Specific device by UUID</term><description>uuid:&lt;device uuid&gt;</description></item>
/// <item><term>Device type</term><description>A device namespace and type in format of urn:&lt;device namespace&gt;:device:&lt;device type&gt;:&lt;device version&gt; i.e urn:schemas-upnp-org:device:Basic:1</description></item>
/// <item><term>Service type</term><description>A service namespace and type in format of urn:&lt;service namespace&gt;:service:&lt;servicetype&gt;:&lt;service version&gt; i.e urn:my-namespace:service:MyCustomService:1</description></item>
/// </list>
/// </param>
/// <param name="searchWaitTime">The amount of time to wait for network responses to the search request. Longer values will likely return more devices, but increase search time. A value between 1 and 5 is recommended by the UPnP 1.1 specification. Specify TimeSpan.Zero to return only devices already in the cache.</param>
/// <remarks>
/// <para>By design RSSDP does not support 'publishing services' as it is intended for use with non-standard UPnP devices that don't publish UPnP style services. However, it is still possible to use RSSDP to search for devices implemetning these services if you know the service type.</para>
/// </remarks>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(string searchTarget, TimeSpan searchWaitTime);
#endregion
/// <summary>
/// Starts listening for broadcast notifications of service availability.
/// </summary>
/// <remarks>
/// <para>When called the system will listen for 'alive' and 'byebye' notifications. This can speed up searching, as well as provide dynamic notification of new devices appearing on the network, and previously discovered devices disappearing.</para>
/// </remarks>
/// <seealso cref="StopListeningForNotifications"/>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="NotificationFilter"/>
void StartListeningForNotifications();
/// <summary>
/// Performs a search for all devices using the specified search timeout.
/// </summary>
/// <param name="searchWaitTime">The amount of time to wait for network responses to the search request. Longer values will likely return more devices, but increase search time. A value between 1 and 5 is recommended by the UPnP 1.1 specification. Specify TimeSpan.Zero to return only devices already in the cache.</param>
/// <returns>A task whose result is an <see cref="System.Collections.Generic.IEnumerable{T}"/> of <see cref="DiscoveredSsdpDevice" /> instances, representing all found devices.</returns>
System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(TimeSpan searchWaitTime);
/// <summary>
/// Stops listening for broadcast notifications of service availability.
/// </summary>
/// <remarks>
/// <para>Does nothing if this instance is not already listening for notifications.</para>
/// </remarks>
/// <exception cref="System.ObjectDisposedException">Throw if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true.</exception>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="NotificationFilter"/>
void StopListeningForNotifications();
#endregion
#endregion
/// <summary>
/// Starts listening for broadcast notifications of service availability.
/// </summary>
/// <remarks>
/// <para>When called the system will listen for 'alive' and 'byebye' notifications. This can speed up searching, as well as provide dynamic notification of new devices appearing on the network, and previously discovered devices disappearing.</para>
/// </remarks>
/// <seealso cref="StopListeningForNotifications"/>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="NotificationFilter"/>
void StartListeningForNotifications();
}
}
/// <summary>
/// Stops listening for broadcast notifications of service availability.
/// </summary>
/// <remarks>
/// <para>Does nothing if this instance is not already listening for notifications.</para>
/// </remarks>
/// <exception cref="System.ObjectDisposedException">Throw if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true.</exception>
/// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="NotificationFilter"/>
void StopListeningForNotifications();
#endregion
}
}

View file

@ -3,35 +3,34 @@ using System.Threading.Tasks;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Interface for components that publish the existence of SSDP devices.
/// </summary>
/// <remarks>
/// <para>Publishing a device includes sending notifications (alive and byebye) as well as responding to search requests when appropriate.</para>
/// </remarks>
/// <seealso cref="SsdpRootDevice"/>
/// <seealso cref="ISsdpDeviceLocator"/>
public interface ISsdpDevicePublisher
{
/// <summary>
/// Adds a device (and it's children) to the list of devices being published by this server, making them discoverable to SSDP clients.
/// </summary>
/// <param name="device">The <see cref="SsdpRootDevice"/> instance to add.</param>
/// <returns>An awaitable <see cref="System.Threading.Tasks.Task"/>.</returns>
void AddDevice(SsdpRootDevice device);
/// <summary>
/// Interface for components that publish the existence of SSDP devices.
/// </summary>
/// <remarks>
/// <para>Publishing a device includes sending notifications (alive and byebye) as well as responding to search requests when appropriate.</para>
/// </remarks>
/// <seealso cref="SsdpRootDevice"/>
/// <seealso cref="ISsdpDeviceLocator"/>
public interface ISsdpDevicePublisher
{
/// <summary>
/// Adds a device (and it's children) to the list of devices being published by this server, making them discoverable to SSDP clients.
/// </summary>
/// <param name="device">The <see cref="SsdpRootDevice"/> instance to add.</param>
/// <returns>An awaitable <see cref="System.Threading.Tasks.Task"/>.</returns>
void AddDevice(SsdpRootDevice device);
/// <summary>
/// Removes a device (and it's children) from the list of devices being published by this server, making them undiscoverable.
/// </summary>
/// <param name="device">The <see cref="SsdpRootDevice"/> instance to add.</param>
/// <returns>An awaitable <see cref="System.Threading.Tasks.Task"/>.</returns>
Task RemoveDevice(SsdpRootDevice device);
/// <summary>
/// Removes a device (and it's children) from the list of devices being published by this server, making them undiscoverable.
/// </summary>
/// <param name="device">The <see cref="SsdpRootDevice"/> instance to add.</param>
/// <returns>An awaitable <see cref="System.Threading.Tasks.Task"/>.</returns>
Task RemoveDevice(SsdpRootDevice device);
/// <summary>
/// Returns a read only list of devices being published by this instance.
/// </summary>
/// <seealso cref="SsdpDevice"/>
System.Collections.Generic.IEnumerable<SsdpRootDevice> Devices { get; }
}
/// <summary>
/// Returns a read only list of devices being published by this instance.
/// </summary>
/// <seealso cref="SsdpDevice"/>
System.Collections.Generic.IEnumerable<SsdpRootDevice> Devices { get; }
}
}

View file

@ -8,54 +8,52 @@ using MediaBrowser.Model.Net;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Provides arguments for the <see cref="ISsdpCommunicationsServer.RequestReceived"/> event.
/// </summary>
public sealed class RequestReceivedEventArgs : EventArgs
{
/// <summary>
/// Provides arguments for the <see cref="ISsdpCommunicationsServer.RequestReceived"/> event.
/// </summary>
public sealed class RequestReceivedEventArgs : EventArgs
{
#region Fields
#region Fields
private readonly HttpRequestMessage _Message;
private readonly IpEndPointInfo _ReceivedFrom;
private readonly HttpRequestMessage _Message;
private readonly IpEndPointInfo _ReceivedFrom;
#endregion
#endregion
public IpAddressInfo LocalIpAddress { get; private set; }
public IpAddressInfo LocalIpAddress { get; private set; }
#region Constructors
#region Constructors
/// <summary>
/// Full constructor.
/// </summary>
public RequestReceivedEventArgs(HttpRequestMessage message, IpEndPointInfo receivedFrom, IpAddressInfo localIpAddress)
{
_Message = message;
_ReceivedFrom = receivedFrom;
LocalIpAddress = localIpAddress;
}
/// <summary>
/// Full constructor.
/// </summary>
public RequestReceivedEventArgs(HttpRequestMessage message, IpEndPointInfo receivedFrom, IpAddressInfo localIpAddress)
{
_Message = message;
_ReceivedFrom = receivedFrom;
LocalIpAddress = localIpAddress;
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// The <see cref="HttpRequestMessage"/> that was received.
/// </summary>
public HttpRequestMessage Message
{
get { return _Message; }
}
/// <summary>
/// The <see cref="HttpRequestMessage"/> that was received.
/// </summary>
public HttpRequestMessage Message
{
get { return _Message; }
}
/// <summary>
/// The <see cref="UdpEndPoint"/> the request came from.
/// </summary>
public IpEndPointInfo ReceivedFrom
{
get { return _ReceivedFrom; }
}
/// <summary>
/// The <see cref="UdpEndPoint"/> the request came from.
/// </summary>
public IpEndPointInfo ReceivedFrom
{
get { return _ReceivedFrom; }
}
#endregion
}
}
#endregion
}
}

View file

@ -8,53 +8,52 @@ using MediaBrowser.Model.Net;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Provides arguments for the <see cref="ISsdpCommunicationsServer.ResponseReceived"/> event.
/// </summary>
public sealed class ResponseReceivedEventArgs : EventArgs
{
/// <summary>
/// Provides arguments for the <see cref="ISsdpCommunicationsServer.ResponseReceived"/> event.
/// </summary>
public sealed class ResponseReceivedEventArgs : EventArgs
{
public IpAddressInfo LocalIpAddress { get; set; }
#region Fields
private readonly HttpResponseMessage _Message;
private readonly IpEndPointInfo _ReceivedFrom;
private readonly IpEndPointInfo _ReceivedFrom;
#endregion
#endregion
#region Constructors
#region Constructors
/// <summary>
/// Full constructor.
/// </summary>
public ResponseReceivedEventArgs(HttpResponseMessage message, IpEndPointInfo receivedFrom)
{
_Message = message;
_ReceivedFrom = receivedFrom;
}
/// <summary>
/// Full constructor.
/// </summary>
public ResponseReceivedEventArgs(HttpResponseMessage message, IpEndPointInfo receivedFrom)
{
_Message = message;
_ReceivedFrom = receivedFrom;
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// The <see cref="HttpResponseMessage"/> that was received.
/// </summary>
public HttpResponseMessage Message
{
get { return _Message; }
}
/// <summary>
/// The <see cref="HttpResponseMessage"/> that was received.
/// </summary>
public HttpResponseMessage Message
{
get { return _Message; }
}
/// <summary>
/// The <see cref="UdpEndPoint"/> the response came from.
/// </summary>
public IpEndPointInfo ReceivedFrom
{
get { return _ReceivedFrom; }
}
/// <summary>
/// The <see cref="UdpEndPoint"/> the response came from.
/// </summary>
public IpEndPointInfo ReceivedFrom
{
get { return _ReceivedFrom; }
}
#endregion
}
#endregion
}
}

View file

@ -20,22 +20,19 @@ namespace Rssdp.Infrastructure
#region Fields
/*
We could technically use one socket listening on port 1900 for everything.
This should get both multicast (notifications) and unicast (search response) messages, however
this often doesn't work under Windows because the MS SSDP service is running. If that service
is running then it will steal the unicast messages and we will never see search responses.
Since stopping the service would be a bad idea (might not be allowed security wise and might
break other apps running on the system) the only other work around is to use two sockets.
We use one socket to listen for/receive notifications and search requests (_BroadcastListenSocket).
We use a second socket, bound to a different local port, to send search requests and listen for
responses (_SendSocket). The responses are sent to the local port this socket is bound to,
which isn't port 1900 so the MS service doesn't steal them. While the caller can specify a local
port to use, we will default to 0 which allows the underlying system to auto-assign a free port.
*/
/* We could technically use one socket listening on port 1900 for everything.
* This should get both multicast (notifications) and unicast (search response) messages, however
* this often doesn't work under Windows because the MS SSDP service is running. If that service
* is running then it will steal the unicast messages and we will never see search responses.
* Since stopping the service would be a bad idea (might not be allowed security wise and might
* break other apps running on the system) the only other work around is to use two sockets.
*
* We use one socket to listen for/receive notifications and search requests (_BroadcastListenSocket).
* We use a second socket, bound to a different local port, to send search requests and listen for
* responses (_SendSocket). The responses are sent to the local port this socket is bound to,
* which isn't port 1900 so the MS service doesn't steal them. While the caller can specify a local
* port to use, we will default to 0 which allows the underlying system to auto-assign a free port.
*/
private object _BroadcastListenSocketSynchroniser = new object();
private ISocket _BroadcastListenSocket;
@ -443,7 +440,7 @@ namespace Rssdp.Infrastructure
private void ProcessMessage(string data, IpEndPointInfo endPoint, IpAddressInfo receivedOnLocalIpAddress)
{
//Responses start with the HTTP version, prefixed with HTTP/ while
//requests start with a method which can vary and might be one we haven't
//requests start with a method which can vary and might be one we haven't
//seen/don't know. We'll check if this message is a request or a response
//by checking for the HTTP/ prefix on the start of the message.
if (data.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase))

View file

@ -5,63 +5,63 @@ using System.Threading.Tasks;
namespace Rssdp.Infrastructure
{
/// <summary>
/// Provides constants for common values related to the SSDP protocols.
/// </summary>
public static class SsdpConstants
{
/// <summary>
/// Provides constants for common values related to the SSDP protocols.
/// </summary>
public static class SsdpConstants
{
/// <summary>
/// Multicast IP Address used for SSDP multicast messages. Values is 239.255.255.250.
/// </summary>
public const string MulticastLocalAdminAddress = "239.255.255.250";
/// <summary>
/// The UDP port used for SSDP multicast messages. Values is 1900.
/// </summary>
public const int MulticastPort = 1900;
/// <summary>
/// The default multicase TTL for SSDP multicast messages. Value is 4.
/// </summary>
public const int SsdpDefaultMulticastTimeToLive = 4;
/// <summary>
/// Multicast IP Address used for SSDP multicast messages. Values is 239.255.255.250.
/// </summary>
public const string MulticastLocalAdminAddress = "239.255.255.250";
/// <summary>
/// The UDP port used for SSDP multicast messages. Values is 1900.
/// </summary>
public const int MulticastPort = 1900;
/// <summary>
/// The default multicase TTL for SSDP multicast messages. Value is 4.
/// </summary>
public const int SsdpDefaultMulticastTimeToLive = 4;
internal const string MSearchMethod = "M-SEARCH";
internal const string MSearchMethod = "M-SEARCH";
internal const string SsdpDiscoverMessage = "ssdp:discover";
internal const string SsdpDiscoverAllSTHeader = "ssdp:all";
internal const string SsdpDiscoverMessage = "ssdp:discover";
internal const string SsdpDiscoverAllSTHeader = "ssdp:all";
internal const string SsdpDeviceDescriptionXmlNamespace = "urn:schemas-upnp-org:device-1-0";
internal const string SsdpDeviceDescriptionXmlNamespace = "urn:schemas-upnp-org:device-1-0";
/// <summary>
/// Default buffer size for receiving SSDP broadcasts. Value is 8192 (bytes).
/// </summary>
public const int DefaultUdpSocketBufferSize = 8192;
/// <summary>
/// The maximum possible buffer size for a UDP message. Value is 65507 (bytes).
/// </summary>
public const int MaxUdpSocketBufferSize = 65507; // Max possible UDP packet size on IPv4 without using 'jumbograms'.
/// <summary>
/// Default buffer size for receiving SSDP broadcasts. Value is 8192 (bytes).
/// </summary>
public const int DefaultUdpSocketBufferSize = 8192;
/// <summary>
/// The maximum possible buffer size for a UDP message. Value is 65507 (bytes).
/// </summary>
public const int MaxUdpSocketBufferSize = 65507; // Max possible UDP packet size on IPv4 without using 'jumbograms'.
/// <summary>
/// Namespace/prefix for UPnP device types. Values is schemas-upnp-org.
/// </summary>
public const string UpnpDeviceTypeNamespace = "schemas-upnp-org";
/// <summary>
/// UPnP Root Device type. Value is upnp:rootdevice.
/// </summary>
public const string UpnpDeviceTypeRootDevice = "upnp:rootdevice";
/// <summary>
/// The value is used by Windows Explorer for device searches instead of the UPNPDeviceTypeRootDevice constant.
/// Not sure why (different spec, bug, alternate protocol etc). Used to enable Windows Explorer support.
/// </summary>
public const string PnpDeviceTypeRootDevice = "pnp:rootdevice";
/// <summary>
/// UPnP Basic Device type. Value is Basic.
/// </summary>
public const string UpnpDeviceTypeBasicDevice = "Basic";
/// <summary>
/// Namespace/prefix for UPnP device types. Values is schemas-upnp-org.
/// </summary>
public const string UpnpDeviceTypeNamespace = "schemas-upnp-org";
/// <summary>
/// UPnP Root Device type. Value is upnp:rootdevice.
/// </summary>
public const string UpnpDeviceTypeRootDevice = "upnp:rootdevice";
/// <summary>
/// The value is used by Windows Explorer for device searches instead of the UPNPDeviceTypeRootDevice constant.
/// Not sure why (different spec, bug, alternate protocol etc). Used to enable Windows Explorer support.
/// </summary>
public const string PnpDeviceTypeRootDevice = "pnp:rootdevice";
/// <summary>
/// UPnP Basic Device type. Value is Basic.
/// </summary>
public const string UpnpDeviceTypeBasicDevice = "Basic";
internal const string SsdpKeepAliveNotification = "ssdp:alive";
internal const string SsdpByeByeNotification = "ssdp:byebye";
internal const string SsdpKeepAliveNotification = "ssdp:alive";
internal const string SsdpByeByeNotification = "ssdp:byebye";
internal const int UdpResendCount = 3;
internal const int UdpResendCount = 3;
}
}
}

View file

@ -75,7 +75,7 @@ namespace Rssdp
return rootDevice;
}
#region Public Properties
#region UPnP Device Description Properties
@ -330,7 +330,7 @@ namespace Rssdp
/// </summary>
/// <param name="device">The <see cref="SsdpEmbeddedDevice"/> instance added to the <see cref="Devices"/> collection.</param>
/// <seealso cref="AddDevice"/>
/// <seealso cref="DeviceAdded"/>
/// <seealso cref="DeviceAdded"/>
protected virtual void OnDeviceAdded(SsdpEmbeddedDevice device)
{
var handlers = this.DeviceAdded;

View file

@ -418,7 +418,7 @@ namespace Rssdp.Infrastructure
var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
// If needed later for non-server devices, these headers will need to be dynamic
// If needed later for non-server devices, these headers will need to be dynamic
values["HOST"] = "239.255.255.250:1900";
values["DATE"] = DateTime.UtcNow.ToString("r");
values["CACHE-CONTROL"] = "max-age = " + rootDevice.CacheLifetime.TotalSeconds;
@ -463,7 +463,7 @@ namespace Rssdp.Infrastructure
var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
// If needed later for non-server devices, these headers will need to be dynamic
// If needed later for non-server devices, these headers will need to be dynamic
values["HOST"] = "239.255.255.250:1900";
values["DATE"] = DateTime.UtcNow.ToString("r");
values["SERVER"] = string.Format("{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, ServerVersion);
@ -538,9 +538,9 @@ namespace Rssdp.Infrastructure
//According to SSDP/UPnP spec, ignore message if missing these headers.
// Edit: But some devices do it anyway
//if (!e.Message.Headers.Contains("MX"))
// WriteTrace("Ignoring search request - missing MX header.");
// WriteTrace("Ignoring search request - missing MX header.");
//else if (!e.Message.Headers.Contains("MAN"))
// WriteTrace("Ignoring search request - missing MAN header.");
// WriteTrace("Ignoring search request - missing MAN header.");
//else
ProcessSearchRequest(GetFirstHeaderValue(e.Message.Headers, "MX"), GetFirstHeaderValue(e.Message.Headers, "ST"), e.ReceivedFrom, e.LocalIpAddress, CancellationToken.None);
}

View file

@ -4,54 +4,52 @@ using System.Text;
namespace Rssdp
{
/// <summary>
/// Represents a device that is a descendant of a <see cref="SsdpRootDevice"/> instance.
/// </summary>
public class SsdpEmbeddedDevice : SsdpDevice
{
/// <summary>
/// Represents a device that is a descendant of a <see cref="SsdpRootDevice"/> instance.
/// </summary>
public class SsdpEmbeddedDevice : SsdpDevice
{
#region Fields
private SsdpRootDevice _RootDevice;
#region Fields
private SsdpRootDevice _RootDevice;
#endregion
#endregion
#region Constructors
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
public SsdpEmbeddedDevice()
{
}
/// <summary>
/// Default constructor.
/// </summary>
public SsdpEmbeddedDevice()
{
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Returns the <see cref="SsdpRootDevice"/> that is this device's first ancestor. If this device is itself an <see cref="SsdpRootDevice"/>, then returns a reference to itself.
/// </summary>
public SsdpRootDevice RootDevice
{
get
{
return _RootDevice;
}
internal set
{
_RootDevice = value;
lock (this.Devices)
{
foreach (var embeddedDevice in this.Devices)
{
((SsdpEmbeddedDevice)embeddedDevice).RootDevice = _RootDevice;
}
}
}
}
/// <summary>
/// Returns the <see cref="SsdpRootDevice"/> that is this device's first ancestor. If this device is itself an <see cref="SsdpRootDevice"/>, then returns a reference to itself.
/// </summary>
public SsdpRootDevice RootDevice
{
get
{
return _RootDevice;
}
internal set
{
_RootDevice = value;
lock (this.Devices)
{
foreach (var embeddedDevice in this.Devices)
{
((SsdpEmbeddedDevice)embeddedDevice).RootDevice = _RootDevice;
}
}
}
}
#endregion
}
}
#endregion
}
}

View file

@ -6,74 +6,72 @@ using Rssdp.Infrastructure;
namespace Rssdp
{
/// <summary>
/// Represents a 'root' device, a device that has no parent. Used for publishing devices and for the root device in a tree of discovered devices.
/// </summary>
/// <remarks>
/// <para>Child (embedded) devices are represented by the <see cref="SsdpDevice"/> in the <see cref="SsdpDevice.Devices"/> property.</para>
/// <para>Root devices contain some information that applies to the whole device tree and is therefore not present on child devices, such as <see cref="CacheLifetime"/> and <see cref="Location"/>.</para>
/// </remarks>
public class SsdpRootDevice : SsdpDevice
{
#region Fields
/// <summary>
/// Represents a 'root' device, a device that has no parent. Used for publishing devices and for the root device in a tree of discovered devices.
/// </summary>
/// <remarks>
/// <para>Child (embedded) devices are represented by the <see cref="SsdpDevice"/> in the <see cref="SsdpDevice.Devices"/> property.</para>
/// <para>Root devices contain some information that applies to the whole device tree and is therefore not present on child devices, such as <see cref="CacheLifetime"/> and <see cref="Location"/>.</para>
/// </remarks>
public class SsdpRootDevice : SsdpDevice
{
#region Fields
private Uri _UrlBase;
private Uri _UrlBase;
#endregion
#endregion
#region Constructors
#region Constructors
/// <summary>
/// Default constructor.
/// </summary>
public SsdpRootDevice() : base()
{
}
/// <summary>
/// Default constructor.
/// </summary>
public SsdpRootDevice() : base()
{
}
#endregion
#endregion
#region Public Properties
#region Public Properties
/// <summary>
/// Specifies how long clients can cache this device's details for. Optional but defaults to <see cref="TimeSpan.Zero"/> which means no-caching. Recommended value is half an hour.
/// </summary>
/// <remarks>
/// <para>Specifiy <see cref="TimeSpan.Zero"/> to indicate no caching allowed.</para>
/// <para>Also used to specify how often to rebroadcast alive notifications.</para>
/// <para>The UPnP/SSDP specifications indicate this should not be less than 1800 seconds (half an hour), but this is not enforced by this library.</para>
/// </remarks>
public TimeSpan CacheLifetime
{
get; set;
}
/// <summary>
/// Specifies how long clients can cache this device's details for. Optional but defaults to <see cref="TimeSpan.Zero"/> which means no-caching. Recommended value is half an hour.
/// </summary>
/// <remarks>
/// <para>Specifiy <see cref="TimeSpan.Zero"/> to indicate no caching allowed.</para>
/// <para>Also used to specify how often to rebroadcast alive notifications.</para>
/// <para>The UPnP/SSDP specifications indicate this should not be less than 1800 seconds (half an hour), but this is not enforced by this library.</para>
/// </remarks>
public TimeSpan CacheLifetime
{
get; set;
}
/// <summary>
/// Gets or sets the URL used to retrieve the description document for this device/tree. Required.
/// </summary>
public Uri Location { get; set; }
/// <summary>
/// Gets or sets the URL used to retrieve the description document for this device/tree. Required.
/// </summary>
public Uri Location { get; set; }
/// <summary>
/// The base URL to use for all relative url's provided in other propertise (and those of child devices). Optional.
/// </summary>
/// <remarks>
/// <para>Defines the base URL. Used to construct fully-qualified URLs. All relative URLs that appear elsewhere in the description are combined with this base URL. If URLBase is empty or not given, the base URL is the URL from which the device description was retrieved (which is the preferred implementation; use of URLBase is no longer recommended). Specified by UPnP vendor. Single URL.</para>
/// </remarks>
public Uri UrlBase
{
get
{
return _UrlBase ?? this.Location;
}
/// <summary>
/// The base URL to use for all relative url's provided in other propertise (and those of child devices). Optional.
/// </summary>
/// <remarks>
/// <para>Defines the base URL. Used to construct fully-qualified URLs. All relative URLs that appear elsewhere in the description are combined with this base URL. If URLBase is empty or not given, the base URL is the URL from which the device description was retrieved (which is the preferred implementation; use of URLBase is no longer recommended). Specified by UPnP vendor. Single URL.</para>
/// </remarks>
public Uri UrlBase
{
get
{
return _UrlBase ?? this.Location;
}
set
{
_UrlBase = value;
}
}
set
{
_UrlBase = value;
}
}
#endregion
}
#endregion
}
}

View file

@ -14,7 +14,7 @@ namespace SocketHttpListener.Net
// System.Net.ResponseStream
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
//
@ -25,10 +25,10 @@ namespace SocketHttpListener.Net
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

View file

@ -12,7 +12,7 @@ namespace SocketHttpListener.Net
// System.Net.ResponseStream
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
//

View file

@ -207,13 +207,13 @@ namespace SocketHttpListener.Net
}
/* Apache forces closing the connection for these status codes:
* HttpStatusCode.BadRequest 400
* HttpStatusCode.RequestTimeout 408
* HttpStatusCode.LengthRequired 411
* HttpStatusCode.RequestEntityTooLarge 413
* HttpStatusCode.RequestUriTooLong 414
* HttpStatusCode.InternalServerError 500
* HttpStatusCode.ServiceUnavailable 503
* HttpStatusCode.BadRequest 400
* HttpStatusCode.RequestTimeout 408
* HttpStatusCode.LengthRequired 411
* HttpStatusCode.RequestEntityTooLarge 413
* HttpStatusCode.RequestUriTooLong 414
* HttpStatusCode.InternalServerError 500
* HttpStatusCode.ServiceUnavailable 503
*/
bool conn_close = (_statusCode == (int)HttpStatusCode.BadRequest || _statusCode == (int)HttpStatusCode.RequestTimeout
|| _statusCode == (int)HttpStatusCode.LengthRequired || _statusCode == (int)HttpStatusCode.RequestEntityTooLarge

View file

@ -13,7 +13,7 @@ namespace SocketHttpListener.Net
// System.Net.ResponseStream
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
//
@ -24,10 +24,10 @@ namespace SocketHttpListener.Net
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

View file

@ -13,7 +13,7 @@ namespace SocketHttpListener.Net
// System.Net.ResponseStream
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
//
@ -24,10 +24,10 @@ namespace SocketHttpListener.Net
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

View file

@ -19,7 +19,7 @@ namespace SocketHttpListener.Net
// System.Net.ResponseStream
//
// Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com)
// Gonzalo Paniagua Javier (gonzalo@novell.com)
//
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
//
@ -30,10 +30,10 @@ namespace SocketHttpListener.Net
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

View file

@ -23,69 +23,69 @@ namespace SocketHttpListener.Net
}
static readonly bool[] allowed_chars = {
false, false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, true, false, true, true, true, true, false, false, false, true,
true, false, true, true, false, true, true, true, true, true, true, true, true, true, true, false,
false, false, false, false, false, false, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
false, true, false
};
false, false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false, false, false, false, false, false,
false, false, false, false, false, true, false, true, true, true, true, false, false, false, true,
true, false, true, true, false, true, true, true, true, true, true, true, true, true, true, false,
false, false, false, false, false, false, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true,
true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
false, true, false
};
static readonly Dictionary<string, HeaderInfo> headers;
static WebHeaderCollection()
{
headers = new Dictionary<string, HeaderInfo>(StringComparer.OrdinalIgnoreCase) {
{ "Allow", HeaderInfo.MultiValue },
{ "Accept", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Accept-Charset", HeaderInfo.MultiValue },
{ "Accept-Encoding", HeaderInfo.MultiValue },
{ "Accept-Language", HeaderInfo.MultiValue },
{ "Accept-Ranges", HeaderInfo.MultiValue },
{ "Age", HeaderInfo.Response },
{ "Authorization", HeaderInfo.MultiValue },
{ "Cache-Control", HeaderInfo.MultiValue },
{ "Cookie", HeaderInfo.MultiValue },
{ "Connection", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Content-Encoding", HeaderInfo.MultiValue },
{ "Content-Length", HeaderInfo.Request | HeaderInfo.Response },
{ "Content-Type", HeaderInfo.Request },
{ "Content-Language", HeaderInfo.MultiValue },
{ "Date", HeaderInfo.Request },
{ "Expect", HeaderInfo.Request | HeaderInfo.MultiValue},
{ "Host", HeaderInfo.Request },
{ "If-Match", HeaderInfo.MultiValue },
{ "If-Modified-Since", HeaderInfo.Request },
{ "If-None-Match", HeaderInfo.MultiValue },
{ "Keep-Alive", HeaderInfo.Response },
{ "Pragma", HeaderInfo.MultiValue },
{ "Proxy-Authenticate", HeaderInfo.MultiValue },
{ "Proxy-Authorization", HeaderInfo.MultiValue },
{ "Proxy-Connection", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Range", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Referer", HeaderInfo.Request },
{ "Set-Cookie", HeaderInfo.MultiValue },
{ "Set-Cookie2", HeaderInfo.MultiValue },
{ "Server", HeaderInfo.Response },
{ "TE", HeaderInfo.MultiValue },
{ "Trailer", HeaderInfo.MultiValue },
{ "Transfer-Encoding", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo.MultiValue },
{ "Translate", HeaderInfo.Request | HeaderInfo.Response },
{ "Upgrade", HeaderInfo.MultiValue },
{ "User-Agent", HeaderInfo.Request },
{ "Vary", HeaderInfo.MultiValue },
{ "Via", HeaderInfo.MultiValue },
{ "Warning", HeaderInfo.MultiValue },
{ "WWW-Authenticate", HeaderInfo.Response | HeaderInfo. MultiValue },
{ "SecWebSocketAccept", HeaderInfo.Response },
{ "SecWebSocketExtensions", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo. MultiValue },
{ "SecWebSocketKey", HeaderInfo.Request },
{ "Sec-WebSocket-Protocol", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo. MultiValue },
{ "SecWebSocketVersion", HeaderInfo.Response | HeaderInfo. MultiValue }
};
{ "Allow", HeaderInfo.MultiValue },
{ "Accept", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Accept-Charset", HeaderInfo.MultiValue },
{ "Accept-Encoding", HeaderInfo.MultiValue },
{ "Accept-Language", HeaderInfo.MultiValue },
{ "Accept-Ranges", HeaderInfo.MultiValue },
{ "Age", HeaderInfo.Response },
{ "Authorization", HeaderInfo.MultiValue },
{ "Cache-Control", HeaderInfo.MultiValue },
{ "Cookie", HeaderInfo.MultiValue },
{ "Connection", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Content-Encoding", HeaderInfo.MultiValue },
{ "Content-Length", HeaderInfo.Request | HeaderInfo.Response },
{ "Content-Type", HeaderInfo.Request },
{ "Content-Language", HeaderInfo.MultiValue },
{ "Date", HeaderInfo.Request },
{ "Expect", HeaderInfo.Request | HeaderInfo.MultiValue},
{ "Host", HeaderInfo.Request },
{ "If-Match", HeaderInfo.MultiValue },
{ "If-Modified-Since", HeaderInfo.Request },
{ "If-None-Match", HeaderInfo.MultiValue },
{ "Keep-Alive", HeaderInfo.Response },
{ "Pragma", HeaderInfo.MultiValue },
{ "Proxy-Authenticate", HeaderInfo.MultiValue },
{ "Proxy-Authorization", HeaderInfo.MultiValue },
{ "Proxy-Connection", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Range", HeaderInfo.Request | HeaderInfo.MultiValue },
{ "Referer", HeaderInfo.Request },
{ "Set-Cookie", HeaderInfo.MultiValue },
{ "Set-Cookie2", HeaderInfo.MultiValue },
{ "Server", HeaderInfo.Response },
{ "TE", HeaderInfo.MultiValue },
{ "Trailer", HeaderInfo.MultiValue },
{ "Transfer-Encoding", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo.MultiValue },
{ "Translate", HeaderInfo.Request | HeaderInfo.Response },
{ "Upgrade", HeaderInfo.MultiValue },
{ "User-Agent", HeaderInfo.Request },
{ "Vary", HeaderInfo.MultiValue },
{ "Via", HeaderInfo.MultiValue },
{ "Warning", HeaderInfo.MultiValue },
{ "WWW-Authenticate", HeaderInfo.Response | HeaderInfo. MultiValue },
{ "SecWebSocketAccept", HeaderInfo.Response },
{ "SecWebSocketExtensions", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo. MultiValue },
{ "SecWebSocketKey", HeaderInfo.Request },
{ "Sec-WebSocket-Protocol", HeaderInfo.Request | HeaderInfo.Response | HeaderInfo. MultiValue },
{ "SecWebSocketVersion", HeaderInfo.Response | HeaderInfo. MultiValue }
};
}
// Methods