Merge branch 'dev' into code-cleanup

This commit is contained in:
Erwin de Haan 2019-01-11 12:50:36 +01:00
commit e2751d42e8
345 changed files with 2991 additions and 3236 deletions

View file

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

View file

@ -10,8 +10,8 @@ namespace Emby.Server.Implementations.Devices
public class DeviceId public class DeviceId
{ {
private readonly IApplicationPaths _appPaths; private readonly IApplicationPaths _appPaths;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly object _syncLock = new object(); private readonly object _syncLock = new object();
@ -23,7 +23,7 @@ namespace Emby.Server.Implementations.Devices
{ {
lock (_syncLock) lock (_syncLock)
{ {
var value = File.ReadAllText(CachePath, Encoding.UTF8); var value = File.ReadAllText(CachePath, Encoding.UTF8);
Guid guid; Guid guid;
if (Guid.TryParse(value, out guid)) if (Guid.TryParse(value, out guid))
@ -54,7 +54,7 @@ namespace Emby.Server.Implementations.Devices
{ {
var path = CachePath; var path = CachePath;
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
lock (_syncLock) lock (_syncLock)
{ {
@ -95,7 +95,7 @@ namespace Emby.Server.Implementations.Devices
_appPaths = appPaths; _appPaths = appPaths;
_logger = logger; _logger = logger;
_fileSystem = fileSystem; _fileSystem = fileSystem;
} }
public string Value => _id ?? (_id = GetDeviceId()); public string Value => _id ?? (_id = GetDeviceId());

View file

@ -1792,11 +1792,11 @@ namespace System.Net
/// <summary> /// <summary>
/// ///
/// Class Leading bits Default netmask /// Class Leading bits Default netmask
/// A (CIDR /8) 00 255.0.0.0 /// A (CIDR /8) 00 255.0.0.0
/// A (CIDR /8) 01 255.0.0.0 /// A (CIDR /8) 01 255.0.0.0
/// B (CIDR /16) 10 255.255.0.0 /// B (CIDR /16) 10 255.255.0.0
/// C (CIDR /24) 11 255.255.255.0 /// C (CIDR /24) 11 255.255.255.0
/// ///
/// </summary> /// </summary>
/// <param name="ip"></param> /// <param name="ip"></param>

View file

@ -43,7 +43,6 @@ namespace UniversalDetector.Core
/// </summary> /// </summary>
public abstract class CharDistributionAnalyser public abstract class CharDistributionAnalyser
{ {
protected const float SURE_YES = 0.99f; protected const float SURE_YES = 0.99f;
protected const float SURE_NO = 0.01f; protected const float SURE_NO = 0.01f;
protected const int MINIMUM_DATA_THRESHOLD = 4; protected const int MINIMUM_DATA_THRESHOLD = 4;
@ -401,7 +400,7 @@ namespace UniversalDetector.Core
852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, //last 512 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, 5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636,
@ -980,7 +979,7 @@ namespace UniversalDetector.Core
2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, // 8102 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 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 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 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 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
****************************************************************************************/ ****************************************************************************************/
}; };
@ -1216,7 +1215,7 @@ namespace UniversalDetector.Core
670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, //512, 256 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, 2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,
@ -2002,7 +2001,7 @@ namespace UniversalDetector.Core
2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, // 5376 //last 512 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 2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, // 5392
@ -2870,7 +2869,7 @@ namespace UniversalDetector.Core
2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, // 4368 //last 512 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 2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, // 4384
@ -3168,6 +3167,4 @@ namespace UniversalDetector.Core
return -1; return -1;
} }
} }
} }

View file

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

View file

@ -832,23 +832,22 @@ namespace Emby.XmlTv.Classes
public void ProcessNode(XmlReader reader, Action<string> setter, string languageRequired = null, Action<string> allOccurrencesSetter = null) 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</title> * <title lang="es">Homes Under the Hammer - Spanish 2</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</title> * <title lang="en">Homes Under the Hammer - English 2</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</title> * <title lang="">Homes Under the Hammer - Empty Language 2</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</title> * <title>Homes Under the Hammer - No Language 2</title>
<title>Homes Under the Hammer - No Language 2</title> */
*/
/* Expected Behaviour: /* Expected Behaviour:
- Language = Null Homes Under the Hammer - No Language * - Language = Null Homes Under the Hammer - No Language
- Language = "" Homes Under the Hammer - No Language * - Language = "" Homes Under the Hammer - No Language
- Language = es Homes Under the Hammer - Spanish * - Language = es Homes Under the Hammer - Spanish
- Language = en Homes Under the Hammer - English * - Language = en Homes Under the Hammer - English
*/ */
var results = new List<Tuple<string, string>>(); 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) public void ProcessMultipleNodes(XmlReader reader, Action<string> setter, string languageRequired = null)
{ {
/* /* <category lang="en">Property - English</category>
<category lang="en">Property - English</category> * <category lang="en">Property - English 2</category>
<category lang="en">Property - English 2</category> * <category lang="es">Property - Spanish</category>
<category lang="es">Property - Spanish</category> * <category lang="es">Property - Spanish 2</category>
<category lang="es">Property - Spanish 2</category> * <category lang="">Property - Empty Language</category>
<category lang="">Property - Empty Language</category> * <category lang="">Property - Empty Language 2</category>
<category lang="">Property - Empty Language 2</category> * <category>Property - No Language</category>
<category>Property - No Language</category> * <category>Property - No Language 2</category>
<category>Property - No Language 2</category> */
*/
/* Expected Behaviour: /* Expected Behaviour:
- Language = Null Property - No Language / Property - No Language 2 * - Language = Null Property - No Language / Property - No Language 2
- Language = "" Property - Empty Language / Property - Empty Language 2 * - Language = "" Property - Empty Language / Property - Empty Language 2
- Language = es Property - Spanish / Property - Spanish 2 * - Language = es Property - Spanish / Property - Spanish 2
- Language = en Property - English / Property - English 2 * - Language = en Property - English / Property - English 2
*/ */
var currentElementName = reader.Name; var currentElementName = reader.Name;
var values = new[] { new { Language = reader.GetAttribute("lang"), Value = reader.ReadElementContentAsString() } }.ToList(); 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 NET_4_0
if (validateRequestNewMode && !checked_form) { if (validateRequestNewMode && !checked_form) {
// Setting this before calling the validator prevents // Setting this before calling the validator prevents
// possible endless recursion // possible endless recursion
checked_form = true; checked_form = true;
ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form); ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form);
} else } else
#endif #endif
if (validate_form && !checked_form) if (validate_form && !checked_form)
{ {

View file

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

View file

@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// The TVDB API key /// The TVDB API key
/// </summary> /// </summary>
public static readonly string TvdbApiKey = "B89CE93890E9419B"; public static readonly string TvdbApiKey = "OG4V3YJ3FAP7FP2K";
public static readonly string TvdbBaseUrl = "https://www.thetvdb.com/"; public static readonly string TvdbBaseUrl = "https://www.thetvdb.com/";
/// <summary> /// <summary>
/// The banner URL /// The banner URL

View file

@ -1706,7 +1706,8 @@ namespace MediaBrowser.Controller.MediaEncoding
if (string.Equals(outputVideoCodec, "libvpx", StringComparison.OrdinalIgnoreCase)) if (string.Equals(outputVideoCodec, "libvpx", StringComparison.OrdinalIgnoreCase))
{ {
// per docs: // 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); 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, 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, 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); object GetRedirectResult(string url);

View file

@ -46,7 +46,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
_config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating; _config.NamedConfigurationUpdating += _config_NamedConfigurationUpdating;
Utilities.HttpClient = httpClient; Utilities.HttpClient = httpClient;
OpenSubtitles.SetUserAgent("mediabrowser.tv"); OpenSubtitles.SetUserAgent("jellyfin");
} }
private const string PasswordHashPrefix = "h:"; private const string PasswordHashPrefix = "h:";

View file

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

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. /// Implemented by components that can create a platform specific UDP socket implementation, and wrap it in the cross platform <see cref="ISocket"/> interface.
/// </summary> /// </summary>
public interface ISocketFactory public interface ISocketFactory
{ {
/// <summary>
/// <summary> /// Createa a new unicast socket using the specified local port number.
/// Createa a new unicast socket using the specified local port number. /// </summary>
/// </summary> /// <param name="localPort">The local port to bind to.</param>
/// <param name="localPort">The local port to bind to.</param> /// <returns>A <see cref="ISocket"/> implementation.</returns>
/// <returns>A <see cref="ISocket"/> implementation.</returns> ISocket CreateUdpSocket(int localPort);
ISocket CreateUdpSocket(int localPort);
ISocket CreateUdpBroadcastSocket(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. /// Used by the sockets wrapper to hold raw data received from a UDP socket.
/// </summary> /// </summary>
public sealed class SocketReceiveResult public sealed class SocketReceiveResult
{ {
/// <summary> /// <summary>
/// The buffer to place received data into. /// The buffer to place received data into.
/// </summary> /// </summary>
public byte[] Buffer { get; set; } public byte[] Buffer { get; set; }
/// <summary> /// <summary>
/// The number of bytes received. /// The number of bytes received.
/// </summary> /// </summary>
public int ReceivedBytes { get; set; } public int ReceivedBytes { get; set; }
/// <summary> /// <summary>
/// The <see cref="IpEndPointInfo"/> the data was received from. /// The <see cref="IpEndPointInfo"/> the data was received from.

View file

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

View file

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

View file

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

View file

@ -37,7 +37,6 @@ namespace MediaBrowser.Providers.Movies
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/movies/{1}?api_key={0}"; private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/movies/{1}?api_key={0}";
// &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
internal static FanartMovieImageProvider Current; internal static FanartMovieImageProvider Current;
@ -270,7 +269,7 @@ namespace MediaBrowser.Providers.Movies
var path = GetFanartJsonPath(id); var path = GetFanartJsonPath(id);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
try try
{ {

View file

@ -168,7 +168,7 @@ namespace MediaBrowser.Providers.Movies
private const string TmdbConfigUrl = BaseMovieDbUrl + "3/configuration?api_key={0}"; private const string TmdbConfigUrl = BaseMovieDbUrl + "3/configuration?api_key={0}";
private const string GetMovieInfo3 = BaseMovieDbUrl + @"3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers"; private const string GetMovieInfo3 = BaseMovieDbUrl + @"3/movie/{0}?api_key={1}&append_to_response=casts,releases,images,keywords,trailers";
internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669"; internal static string ApiKey = "4219e299c89411838049ab0dab19ebd5";
internal static string AcceptHeader = "application/json,image/*"; internal static string AcceptHeader = "application/json,image/*";
/// <summary> /// <summary>

View file

@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.Movies
private static readonly CultureInfo EnUs = new CultureInfo("en-US"); private static readonly CultureInfo EnUs = new CultureInfo("en-US");
private const string Search3 = MovieDbProvider.BaseMovieDbUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}"; private const string Search3 = MovieDbProvider.BaseMovieDbUrl + @"3/search/{3}?api_key={1}&query={0}&language={2}";
internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669"; internal static string ApiKey = "4219e299c89411838049ab0dab19ebd5";
internal static string AcceptHeader = "application/json,image/*"; internal static string AcceptHeader = "application/json,image/*";
private readonly ILogger _logger; private readonly ILogger _logger;

View file

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

View file

@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.Music
public static AudioDbArtistProvider Current; public static AudioDbArtistProvider Current;
private const string ApiKey = "49jhsf8248yfahka89724011"; private const string ApiKey = "195003";
public const string BaseUrl = "https://www.theaudiodb.com/api/v1/json/" + ApiKey; public const string BaseUrl = "https://www.theaudiodb.com/api/v1/json/" + ApiKey;
public AudioDbArtistProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClient httpClient, IJsonSerializer json) public AudioDbArtistProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClient httpClient, IJsonSerializer json)

View file

@ -28,7 +28,7 @@ namespace MediaBrowser.Providers.Music
{ {
public class FanartArtistProvider : IRemoteImageProvider, IHasOrder public class FanartArtistProvider : IRemoteImageProvider, IHasOrder
{ {
internal const string ApiKey = "5c6b04c68e904cfed1e6cbc9a9e683d4"; internal const string ApiKey = "184e1a2b1fe3b94935365411f919f638";
private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3.1/music/{1}?api_key={0}"; private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3.1/music/{1}?api_key={0}";
private readonly CultureInfo _usCulture = new CultureInfo("en-US"); private readonly CultureInfo _usCulture = new CultureInfo("en-US");

View file

@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.Omdb
list.Add(new RemoteImageInfo list.Add(new RemoteImageInfo
{ {
ProviderName = Name, ProviderName = Name,
Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=fe53f97e", imdbId) Url = string.Format("https://img.omdbapi.com/?i={0}&apikey=2c9d9507", imdbId)
}); });
} }
} }

View file

@ -270,7 +270,7 @@ namespace MediaBrowser.Providers.Omdb
public static string GetOmdbUrl(string query, IApplicationHost appHost, CancellationToken cancellationToken) public static string GetOmdbUrl(string query, IApplicationHost appHost, CancellationToken cancellationToken)
{ {
const string url = "https://www.omdbapi.com?apikey=fe53f97e"; const string url = "https://www.omdbapi.com?apikey=2c9d9507";
if (string.IsNullOrWhiteSpace(query)) if (string.IsNullOrWhiteSpace(query))
{ {

View file

@ -36,7 +36,6 @@ namespace MediaBrowser.Providers.TV
private readonly IJsonSerializer _json; private readonly IJsonSerializer _json;
private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/tv/{1}?api_key={0}"; private const string FanArtBaseUrl = "https://webservice.fanart.tv/v3/tv/{1}?api_key={0}";
// &client_key=52c813aa7b8c8b3bb87f4797532a2f8c
internal static FanartSeriesProvider Current { get; private set; } internal static FanartSeriesProvider Current { get; private set; }
@ -312,7 +311,7 @@ namespace MediaBrowser.Providers.TV
var path = GetFanartJsonPath(tvdbId); var path = GetFanartJsonPath(tvdbId);
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path)); _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
try try
{ {

View file

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

View file

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

View file

@ -58,27 +58,27 @@ namespace MediaBrowser.Providers.TV
// Process images // Process images
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, series.ProviderIds); 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)) var result = nodes.Select(i => GetImageInfo(i, cancellationToken))
.Where(i => i != null) .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[] { }); 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 height = 225;
var width = 400; var width = 400;
var url = string.Empty; var url = string.Empty;
// Use XmlReader for best performance // Use XmlReader for best performance
using (reader) using (reader)
{ {
reader.MoveToContent(); reader.MoveToContent();
reader.Read(); reader.Read();
@ -146,7 +146,7 @@ namespace MediaBrowser.Providers.TV
reader.Read(); reader.Read();
} }
} }
} }
if (string.IsNullOrEmpty(url)) if (string.IsNullOrEmpty(url))
{ {

View file

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

View file

@ -38,7 +38,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
return false; 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) protected override void WriteCustomElements(BaseItem item, XmlWriter writer)
@ -62,7 +62,15 @@ namespace MediaBrowser.XbmcMetadata.Savers
return list; 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

@ -34,23 +34,22 @@ using System.Threading.Tasks;
namespace Mono.Nat namespace Mono.Nat
{ {
public abstract class AbstractNatDevice : INatDevice public abstract class AbstractNatDevice : INatDevice
{ {
private DateTime lastSeen; private DateTime lastSeen;
protected AbstractNatDevice () protected AbstractNatDevice()
{ {
}
} public abstract IPAddress LocalAddress { get; }
public abstract IPAddress LocalAddress { get; } public DateTime LastSeen
{
get { return lastSeen; }
set { lastSeen = value; }
}
public DateTime LastSeen public abstract Task CreatePortMap(Mapping mapping);
{ }
get { return lastSeen; }
set { lastSeen = value; }
}
public abstract Task CreatePortMap(Mapping mapping);
}
} }

View file

@ -28,9 +28,9 @@ using System;
namespace Mono.Nat namespace Mono.Nat
{ {
public enum Protocol public enum Protocol
{ {
Tcp, Tcp,
Udp Udp
} }
} }

View file

@ -28,18 +28,18 @@ using System;
namespace Mono.Nat namespace Mono.Nat
{ {
public class DeviceEventArgs : EventArgs public class DeviceEventArgs : EventArgs
{ {
private INatDevice device; private INatDevice device;
public DeviceEventArgs(INatDevice device) public DeviceEventArgs(INatDevice device)
{ {
this.device = device; this.device = device;
} }
public INatDevice Device public INatDevice Device
{ {
get { return this.device; } get { return this.device; }
} }
} }
} }

View file

@ -34,12 +34,12 @@ using System.Threading.Tasks;
namespace Mono.Nat namespace Mono.Nat
{ {
public interface INatDevice public interface INatDevice
{ {
Task CreatePortMap (Mapping mapping); Task CreatePortMap (Mapping mapping);
IPAddress LocalAddress { get; } IPAddress LocalAddress { get; }
DateTime LastSeen { get; set; } DateTime LastSeen { get; set; }
} }
} }

View file

@ -30,36 +30,34 @@ using System;
namespace Mono.Nat namespace Mono.Nat
{ {
public class Mapping public class Mapping
{ {
private string description; private string description;
private DateTime expiration; private DateTime expiration;
private int lifetime; private int lifetime;
private int privatePort; private int privatePort;
private Protocol protocol; private Protocol protocol;
private int publicPort; private int publicPort;
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) if (lifetime == int.MaxValue)
: this (protocol, privatePort, publicPort, 0) this.expiration = DateTime.MaxValue;
{ else if (lifetime == 0)
} this.expiration = DateTime.Now;
else
public Mapping (Protocol protocol, int privatePort, int publicPort, int lifetime) this.expiration = DateTime.Now.AddSeconds (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);
}
public string Description public string Description
{ {
@ -67,57 +65,57 @@ namespace Mono.Nat
set { description = value; } set { description = value; }
} }
public Protocol Protocol public Protocol Protocol
{ {
get { return protocol; } get { return protocol; }
internal set { protocol = value; } internal set { protocol = value; }
} }
public int PrivatePort public int PrivatePort
{ {
get { return privatePort; } get { return privatePort; }
internal set { privatePort = value; } internal set { privatePort = value; }
} }
public int PublicPort public int PublicPort
{ {
get { return publicPort; } get { return publicPort; }
internal set { publicPort = value; } internal set { publicPort = value; }
} }
public int Lifetime public int Lifetime
{ {
get { return lifetime; } get { return lifetime; }
internal set { lifetime = value; } internal set { lifetime = value; }
} }
public DateTime Expiration public DateTime Expiration
{ {
get { return expiration; } get { return expiration; }
internal set { expiration = value; } internal set { expiration = value; }
} }
public bool IsExpired () public bool IsExpired()
{ {
return expiration < DateTime.Now; return expiration < DateTime.Now;
} }
public override bool Equals (object obj) public override bool Equals(object obj)
{ {
Mapping other = obj as Mapping; Mapping other = obj as Mapping;
return other == null ? false : this.protocol == other.protocol && return other == null ? false : this.protocol == other.protocol &&
this.privatePort == other.privatePort && this.publicPort == other.publicPort; this.privatePort == other.privatePort && this.publicPort == other.publicPort;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return this.protocol.GetHashCode() ^ this.privatePort.GetHashCode() ^ this.publicPort.GetHashCode(); return this.protocol.GetHashCode() ^ this.privatePort.GetHashCode() ^ this.publicPort.GetHashCode();
} }
public override string ToString( ) public override string ToString()
{ {
return String.Format( "Protocol: {0}, Public Port: {1}, Private Port: {2}, Description: {3}, Expiration: {4}, Lifetime: {5}", 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 ); this.protocol, this.publicPort, this.privatePort, this.description, this.expiration, this.lifetime );
} }
} }
} }

View file

@ -29,28 +29,28 @@ using System;
namespace Mono.Nat.Pmp namespace Mono.Nat.Pmp
{ {
internal static class PmpConstants internal static class PmpConstants
{ {
public const byte Version = (byte)0; public const byte Version = (byte)0;
public const byte OperationCode = (byte)0; public const byte OperationCode = (byte)0;
public const byte OperationCodeUdp = (byte)1; public const byte OperationCodeUdp = (byte)1;
public const byte OperationCodeTcp = (byte)2; public const byte OperationCodeTcp = (byte)2;
public const byte ServerNoop = (byte)128; public const byte ServerNoop = (byte)128;
public const int ClientPort = 5350; public const int ClientPort = 5350;
public const int ServerPort = 5351; public const int ServerPort = 5351;
public const int RetryDelay = 250; public const int RetryDelay = 250;
public const int RetryAttempts = 9; public const int RetryAttempts = 9;
public const int RecommendedLeaseTime = 60 * 60; public const int RecommendedLeaseTime = 60 * 60;
public const int DefaultLeaseTime = RecommendedLeaseTime; public const int DefaultLeaseTime = RecommendedLeaseTime;
public const short ResultCodeSuccess = 0; public const short ResultCodeSuccess = 0;
public const short ResultCodeUnsupportedVersion = 1; public const short ResultCodeUnsupportedVersion = 1;
public const short ResultCodeNotAuthorized = 2; public const short ResultCodeNotAuthorized = 2;
public const short ResultCodeNetworkFailure = 3; public const short ResultCodeNetworkFailure = 3;
public const short ResultCodeOutOfResources = 4; public const short ResultCodeOutOfResources = 4;
public const short ResultCodeUnsupportedOperationCode = 5; public const short ResultCodeUnsupportedOperationCode = 5;
} }
} }

View file

@ -108,8 +108,8 @@ namespace Mono.Nat
foreach (var unicast in properties.UnicastAddresses) foreach (var unicast in properties.UnicastAddresses)
{ {
if (/*unicast.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred if (/*unicast.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
&& unicast.AddressPreferredLifetime != UInt32.MaxValue && unicast.AddressPreferredLifetime != UInt32.MaxValue
&& */unicast.Address.AddressFamily == AddressFamily.InterNetwork) && */unicast.Address.AddressFamily == AddressFamily.InterNetwork)
{ {
var bytes = unicast.Address.GetAddressBytes(); var bytes = unicast.Address.GetAddressBytes();
bytes[3] = 1; bytes[3] = 1;

View file

@ -58,8 +58,8 @@ namespace Mono.Nat
} }
public void Search() public void Search()
{ {
} }
public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint) public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
{ {
@ -71,15 +71,15 @@ namespace Mono.Nat
try try
{ {
/* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection. /* 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 * 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. * page 5 for an overview of device types and their hierarchy.
http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */ * 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 /* 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 /* 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 // We have an internet gateway device now
UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient); 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> /// <returns>The hash as Hexadecimal string</returns>
public static string ComputeHash(Stream stream) public static string ComputeHash(Stream stream)
{ {
byte[] hash = MovieHasher.ComputeMovieHash(stream); byte[] hash = MovieHasher.ComputeMovieHash(stream);
return MovieHasher.ToHexadecimal(hash); return MovieHasher.ToHexadecimal(hash);
} }
/// <summary> /// <summary>

View file

@ -6,11 +6,11 @@ using MediaBrowser.Model.Net;
namespace Rssdp namespace Rssdp
{ {
/// <summary> /// <summary>
/// Event arguments for the <see cref="Rssdp.Infrastructure.SsdpDeviceLocatorBase.DeviceAvailable"/> event. /// Event arguments for the <see cref="Rssdp.Infrastructure.SsdpDeviceLocatorBase.DeviceAvailable"/> event.
/// </summary> /// </summary>
public sealed class DeviceAvailableEventArgs : EventArgs public sealed class DeviceAvailableEventArgs : EventArgs
{ {
public IpAddressInfo LocalIpAddress { get; set; } public IpAddressInfo LocalIpAddress { get; set; }
#region Fields #region Fields

View file

@ -4,19 +4,19 @@ using System.Text;
namespace Rssdp namespace Rssdp
{ {
/// <summary> /// <summary>
/// Event arguments for the <see cref="SsdpDevice.DeviceAdded"/> and <see cref="SsdpDevice.DeviceRemoved"/> events. /// Event arguments for the <see cref="SsdpDevice.DeviceAdded"/> and <see cref="SsdpDevice.DeviceRemoved"/> events.
/// </summary> /// </summary>
public sealed class DeviceEventArgs : EventArgs public sealed class DeviceEventArgs : EventArgs
{ {
#region Fields #region Fields
private readonly SsdpDevice _Device; private readonly SsdpDevice _Device;
#endregion #endregion
#region Constructors #region Constructors
/// <summary> /// <summary>
/// Constructs a new instance for the specified <see cref="SsdpDevice"/>. /// Constructs a new instance for the specified <see cref="SsdpDevice"/>.
@ -27,22 +27,22 @@ namespace Rssdp
{ {
if (device == null) throw new ArgumentNullException(nameof(device)); if (device == null) throw new ArgumentNullException(nameof(device));
_Device = device; _Device = device;
} }
#endregion #endregion
#region Public Properties #region Public Properties
/// <summary> /// <summary>
/// Returns the <see cref="SsdpDevice"/> instance the event being raised for. /// Returns the <see cref="SsdpDevice"/> instance the event being raised for.
/// </summary> /// </summary>
public SsdpDevice Device public SsdpDevice Device
{ {
get { return _Device; } get { return _Device; }
} }
#endregion #endregion
} }
} }

View file

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

View file

@ -5,44 +5,44 @@ using System.Threading.Tasks;
namespace Rssdp.Infrastructure namespace Rssdp.Infrastructure
{ {
/// <summary> /// <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. /// 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> /// </summary>
public abstract class DisposableManagedObjectBase : IDisposable public abstract class DisposableManagedObjectBase : IDisposable
{ {
#region Public Methods #region Public Methods
/// <summary> /// <summary>
/// Override this method and dispose any objects you own the lifetime of if disposing is true; /// Override this method and dispose any objects you own the lifetime of if disposing is true;
/// </summary> /// </summary>
/// <param name="disposing">True if managed objects should be disposed, if false, only unmanaged resources should be released.</param> /// <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); protected abstract void Dispose(bool disposing);
/// <summary> /// <summary>
/// Throws and <see cref="System.ObjectDisposedException"/> if the <see cref="IsDisposed"/> property is true. /// Throws and <see cref="System.ObjectDisposedException"/> if the <see cref="IsDisposed"/> property is true.
/// </summary> /// </summary>
/// <seealso cref="IsDisposed"/> /// <seealso cref="IsDisposed"/>
/// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="IsDisposed"/> property is true.</exception> /// <exception cref="System.ObjectDisposedException">Thrown if the <see cref="IsDisposed"/> property is true.</exception>
/// <seealso cref="Dispose()"/> /// <seealso cref="Dispose()"/>
protected virtual void ThrowIfDisposed() protected virtual void ThrowIfDisposed()
{ {
if (this.IsDisposed) throw new ObjectDisposedException(this.GetType().FullName); if (this.IsDisposed) throw new ObjectDisposedException(this.GetType().FullName);
} }
#endregion #endregion
#region Public Properties #region Public Properties
/// <summary> /// <summary>
/// Sets or returns a boolean indicating whether or not this instance has been disposed. /// Sets or returns a boolean indicating whether or not this instance has been disposed.
/// </summary> /// </summary>
/// <seealso cref="Dispose()"/> /// <seealso cref="Dispose()"/>
public bool IsDisposed public bool IsDisposed
{ {
get; get;
private set; private set;
} }
#endregion #endregion
@ -74,8 +74,8 @@ namespace Rssdp.Infrastructure
/// </remarks> /// </remarks>
/// <seealso cref="IsDisposed"/> /// <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.")] [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; IsDisposed = true;
Dispose(true); Dispose(true);

View file

@ -79,16 +79,16 @@ namespace Rssdp.Infrastructure
} }
} }
/// <summary> /// <summary>
/// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false). /// Returns a boolean indicating whether the specified HTTP header name represents a content header (true), or a message header (false).
/// </summary> /// </summary>
/// <param name="headerName">A string containing the name of the header to return the type of.</param> /// <param name="headerName">A string containing the name of the header to return the type of.</param>
protected override bool IsContentHeader(string headerName) protected override bool IsContentHeader(string headerName)
{ {
return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase); return ContentHeaderNames.Contains(headerName, StringComparer.OrdinalIgnoreCase);
} }
#endregion #endregion
} }
} }

View file

@ -91,7 +91,6 @@ namespace Rssdp.Infrastructure
} }
} }
#endregion #endregion
}
}
} }

View file

@ -12,17 +12,17 @@ namespace Rssdp.Infrastructure
if (source == null) throw new ArgumentNullException(nameof(source)); if (source == null) throw new ArgumentNullException(nameof(source));
if (selector == null) throw new ArgumentNullException(nameof(selector)); if (selector == null) throw new ArgumentNullException(nameof(selector));
return !source.Any() ? source : return !source.Any() ? source :
source.Concat( source.Concat(
source source
.SelectMany(i => selector(i).EmptyIfNull()) .SelectMany(i => selector(i).EmptyIfNull())
.SelectManyRecursive(selector) .SelectManyRecursive(selector)
); );
} }
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source) public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{ {
return source ?? Enumerable.Empty<T>(); return source ?? Enumerable.Empty<T>();
} }
} }
} }

View file

@ -2,140 +2,140 @@
namespace Rssdp.Infrastructure namespace Rssdp.Infrastructure
{ {
/// <summary> /// <summary>
/// Interface for components that discover the existence of SSDP devices. /// Interface for components that discover the existence of SSDP devices.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para>Discovering devices includes explicit search requests as well as listening for broadcast status notifications.</para> /// <para>Discovering devices includes explicit search requests as well as listening for broadcast status notifications.</para>
/// </remarks> /// </remarks>
/// <seealso cref="DiscoveredSsdpDevice"/> /// <seealso cref="DiscoveredSsdpDevice"/>
/// <seealso cref="SsdpDevice"/> /// <seealso cref="SsdpDevice"/>
/// <seealso cref="ISsdpDevicePublisher"/> /// <seealso cref="ISsdpDevicePublisher"/>
public interface ISsdpDeviceLocator public interface ISsdpDeviceLocator
{ {
#region Events #region Events
/// <summary> /// <summary>
/// Event raised when a device becomes available or is found by a search request. /// Event raised when a device becomes available or is found by a search request.
/// </summary> /// </summary>
/// <seealso cref="NotificationFilter"/> /// <seealso cref="NotificationFilter"/>
/// <seealso cref="DeviceUnavailable"/> /// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="StartListeningForNotifications"/> /// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/> /// <seealso cref="StopListeningForNotifications"/>
event EventHandler<DeviceAvailableEventArgs> DeviceAvailable; event EventHandler<DeviceAvailableEventArgs> DeviceAvailable;
/// <summary> /// <summary>
/// Event raised when a device explicitly notifies of shutdown or a device expires from the cache. /// Event raised when a device explicitly notifies of shutdown or a device expires from the cache.
/// </summary> /// </summary>
/// <seeseealso cref="NotificationFilter"/> /// <seeseealso cref="NotificationFilter"/>
/// <seealso cref="DeviceAvailable"/> /// <seealso cref="DeviceAvailable"/>
/// <seealso cref="StartListeningForNotifications"/> /// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/> /// <seealso cref="StopListeningForNotifications"/>
event EventHandler<DeviceUnavailableEventArgs> DeviceUnavailable; event EventHandler<DeviceUnavailableEventArgs> DeviceUnavailable;
#endregion #endregion
#region Properties #region Properties
/// <summary> /// <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. /// 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> /// </summary>
/// <remarks> /// <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>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> /// <para>Example filters follow;</para>
/// <example>upnp:rootdevice</example> /// <example>upnp:rootdevice</example>
/// <example>urn:schemas-upnp-org:device:WANDevice:1</example> /// <example>urn:schemas-upnp-org:device:WANDevice:1</example>
/// <example>"uuid:9F15356CC-95FA-572E-0E99-85B456BD3012"</example> /// <example>"uuid:9F15356CC-95FA-572E-0E99-85B456BD3012"</example>
/// </remarks> /// </remarks>
/// <seealso cref="DeviceAvailable"/> /// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/> /// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="StartListeningForNotifications"/> /// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="StopListeningForNotifications"/> /// <seealso cref="StopListeningForNotifications"/>
string NotificationFilter string NotificationFilter
{ {
get; get;
set; set;
} }
#endregion #endregion
#region Methods #region Methods
#region SearchAsync Overloads #region SearchAsync Overloads
/// <summary> /// <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. /// 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> /// </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> /// <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(); System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync();
/// <summary> /// <summary>
/// Performs a search for the specified search target (criteria) and default search timeout. /// Performs a search for the specified search target (criteria) and default search timeout.
/// </summary> /// </summary>
/// <param name="searchTarget">The criteria for the search. Value can be; /// <param name="searchTarget">The criteria for the search. Value can be;
/// <list type="table"> /// <list type="table">
/// <item><term>Root devices</term><description>upnp:rootdevice</description></item> /// <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>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> /// <item><term>Device type</term><description>Fully qualified device type starting with urn: i.e urn:schemas-upnp-org:Basic:1</description></item>
/// </list> /// </list>
/// </param> /// </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> /// <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); System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(string searchTarget);
/// <summary> /// <summary>
/// Performs a search for the specified search target (criteria) and search timeout. /// Performs a search for the specified search target (criteria) and search timeout.
/// </summary> /// </summary>
/// <param name="searchTarget">The criteria for the search. Value can be; /// <param name="searchTarget">The criteria for the search. Value can be;
/// <list type="table"> /// <list type="table">
/// <item><term>Root devices</term><description>upnp:rootdevice</description></item> /// <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>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>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> /// <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> /// </list>
/// </param> /// </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> /// <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> /// <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> /// <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> /// </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> /// <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); System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(string searchTarget, TimeSpan searchWaitTime);
/// <summary> /// <summary>
/// Performs a search for all devices using the specified search timeout. /// Performs a search for all devices using the specified search timeout.
/// </summary> /// </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> /// <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> /// <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); System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<DiscoveredSsdpDevice>> SearchAsync(TimeSpan searchWaitTime);
#endregion #endregion
/// <summary> /// <summary>
/// Starts listening for broadcast notifications of service availability. /// Starts listening for broadcast notifications of service availability.
/// </summary> /// </summary>
/// <remarks> /// <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> /// <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> /// </remarks>
/// <seealso cref="StopListeningForNotifications"/> /// <seealso cref="StopListeningForNotifications"/>
/// <seealso cref="DeviceAvailable"/> /// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/> /// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="NotificationFilter"/> /// <seealso cref="NotificationFilter"/>
void StartListeningForNotifications(); void StartListeningForNotifications();
/// <summary> /// <summary>
/// Stops listening for broadcast notifications of service availability. /// Stops listening for broadcast notifications of service availability.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// <para>Does nothing if this instance is not already listening for notifications.</para> /// <para>Does nothing if this instance is not already listening for notifications.</para>
/// </remarks> /// </remarks>
/// <exception cref="System.ObjectDisposedException">Throw if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true.</exception> /// <exception cref="System.ObjectDisposedException">Throw if the <see cref="DisposableManagedObjectBase.IsDisposed"/> property is true.</exception>
/// <seealso cref="StartListeningForNotifications"/> /// <seealso cref="StartListeningForNotifications"/>
/// <seealso cref="DeviceAvailable"/> /// <seealso cref="DeviceAvailable"/>
/// <seealso cref="DeviceUnavailable"/> /// <seealso cref="DeviceUnavailable"/>
/// <seealso cref="NotificationFilter"/> /// <seealso cref="NotificationFilter"/>
void StopListeningForNotifications(); void StopListeningForNotifications();
#endregion #endregion
} }
} }

View file

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

View file

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

View file

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

View file

@ -20,22 +20,19 @@ namespace Rssdp.Infrastructure
#region Fields #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
We could technically use one socket listening on port 1900 for everything. * this often doesn't work under Windows because the MS SSDP service is running. If that service
This should get both multicast (notifications) and unicast (search response) messages, however * is running then it will steal the unicast messages and we will never see search responses.
this often doesn't work under Windows because the MS SSDP service is running. If that service * Since stopping the service would be a bad idea (might not be allowed security wise and might
is running then it will steal the unicast messages and we will never see search responses. * break other apps running on the system) the only other work around is to use two sockets.
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
We use one socket to listen for/receive notifications and search requests (_BroadcastListenSocket). * responses (_SendSocket). The responses are sent to the local port this socket is bound to,
We use a second socket, bound to a different local port, to send search requests and listen for * which isn't port 1900 so the MS service doesn't steal them. While the caller can specify a local
responses (_SendSocket). The responses are sent to the local port this socket is bound to, * port to use, we will default to 0 which allows the underlying system to auto-assign a free port.
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 object _BroadcastListenSocketSynchroniser = new object();
private ISocket _BroadcastListenSocket; private ISocket _BroadcastListenSocket;

View file

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

View file

@ -538,9 +538,9 @@ namespace Rssdp.Infrastructure
//According to SSDP/UPnP spec, ignore message if missing these headers. //According to SSDP/UPnP spec, ignore message if missing these headers.
// Edit: But some devices do it anyway // Edit: But some devices do it anyway
//if (!e.Message.Headers.Contains("MX")) //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")) //else if (!e.Message.Headers.Contains("MAN"))
// WriteTrace("Ignoring search request - missing MAN header."); // WriteTrace("Ignoring search request - missing MAN header.");
//else //else
ProcessSearchRequest(GetFirstHeaderValue(e.Message.Headers, "MX"), GetFirstHeaderValue(e.Message.Headers, "ST"), e.ReceivedFrom, e.LocalIpAddress, CancellationToken.None); 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 namespace Rssdp
{ {
/// <summary> /// <summary>
/// Represents a device that is a descendant of a <see cref="SsdpRootDevice"/> instance. /// Represents a device that is a descendant of a <see cref="SsdpRootDevice"/> instance.
/// </summary> /// </summary>
public class SsdpEmbeddedDevice : SsdpDevice public class SsdpEmbeddedDevice : SsdpDevice
{ {
#region Fields #region Fields
private SsdpRootDevice _RootDevice;
private SsdpRootDevice _RootDevice; #endregion
#endregion #region Constructors
#region Constructors /// <summary>
/// Default constructor.
/// </summary>
public SsdpEmbeddedDevice()
{
}
/// <summary> #endregion
/// Default constructor.
/// </summary>
public SsdpEmbeddedDevice()
{
}
#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> #endregion
/// 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
}
} }

View file

@ -6,74 +6,72 @@ using Rssdp.Infrastructure;
namespace Rssdp namespace Rssdp
{ {
/// <summary> /// <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. /// 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> /// </summary>
/// <remarks> /// <remarks>
/// <para>Child (embedded) devices are represented by the <see cref="SsdpDevice"/> in the <see cref="SsdpDevice.Devices"/> property.</para> /// <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> /// <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> /// </remarks>
public class SsdpRootDevice : SsdpDevice public class SsdpRootDevice : SsdpDevice
{ {
#region Fields
#region Fields private Uri _UrlBase;
private Uri _UrlBase; #endregion
#endregion #region Constructors
#region Constructors /// <summary>
/// Default constructor.
/// </summary>
public SsdpRootDevice() : base()
{
}
/// <summary> #endregion
/// Default constructor.
/// </summary>
public SsdpRootDevice() : base()
{
}
#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> /// <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. /// Gets or sets the URL used to retrieve the description document for this device/tree. Required.
/// </summary> /// </summary>
/// <remarks> public Uri Location { get; set; }
/// <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> /// <summary>
/// The base URL to use for all relative url's provided in other propertise (and those of child devices). Optional. /// The base URL to use for all relative url's provided in other propertise (and those of child devices). Optional.
/// </summary> /// </summary>
/// <remarks> /// <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> /// <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> /// </remarks>
public Uri UrlBase public Uri UrlBase
{ {
get get
{ {
return _UrlBase ?? this.Location; return _UrlBase ?? this.Location;
} }
set set
{ {
_UrlBase = value; _UrlBase = value;
} }
} }
#endregion #endregion
}
}
} }

View file

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

View file

@ -12,7 +12,7 @@ namespace SocketHttpListener.Net
// System.Net.ResponseStream // System.Net.ResponseStream
// //
// Author: // Author:
// Gonzalo Paniagua Javier (gonzalo@novell.com) // Gonzalo Paniagua Javier (gonzalo@novell.com)
// //
// Copyright (c) 2005 Novell, Inc. (http://www.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: /* Apache forces closing the connection for these status codes:
* HttpStatusCode.BadRequest 400 * HttpStatusCode.BadRequest 400
* HttpStatusCode.RequestTimeout 408 * HttpStatusCode.RequestTimeout 408
* HttpStatusCode.LengthRequired 411 * HttpStatusCode.LengthRequired 411
* HttpStatusCode.RequestEntityTooLarge 413 * HttpStatusCode.RequestEntityTooLarge 413
* HttpStatusCode.RequestUriTooLong 414 * HttpStatusCode.RequestUriTooLong 414
* HttpStatusCode.InternalServerError 500 * HttpStatusCode.InternalServerError 500
* HttpStatusCode.ServiceUnavailable 503 * HttpStatusCode.ServiceUnavailable 503
*/ */
bool conn_close = (_statusCode == (int)HttpStatusCode.BadRequest || _statusCode == (int)HttpStatusCode.RequestTimeout bool conn_close = (_statusCode == (int)HttpStatusCode.BadRequest || _statusCode == (int)HttpStatusCode.RequestTimeout
|| _statusCode == (int)HttpStatusCode.LengthRequired || _statusCode == (int)HttpStatusCode.RequestEntityTooLarge || _statusCode == (int)HttpStatusCode.LengthRequired || _statusCode == (int)HttpStatusCode.RequestEntityTooLarge

View file

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

View file

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

View file

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

View file

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