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

View File

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

View File

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

View File

@ -43,7 +43,6 @@ namespace UniversalDetector.Core
/// </summary>
public abstract class CharDistributionAnalyser
{
protected const float SURE_YES = 0.99f;
protected const float SURE_NO = 0.01f;
protected const int MINIMUM_DATA_THRESHOLD = 4;
@ -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
/***************************************************************************************
*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,
@ -980,7 +979,7 @@ namespace UniversalDetector.Core
2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, // 8102
/***************************************************************************************
*Everything below is of no interest for detection purpose *
*Everything below is of no interest for detection purpose *
***************************************************************************************
2515,1613,4582,8119,3312,3866,2516,8120,4058,8121,1637,4059,2466,4583,3867,8122, // 8118
@ -1022,7 +1021,7 @@ namespace UniversalDetector.Core
8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,8690,8691,8692,8693, // 8694
8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,8705,8706,8707,8708,8709, // 8710
8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,8720,8721,8722,8723,8724,8725, // 8726
8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973
8726,8727,8728,8729,8730,8731,8732,8733,8734,8735,8736,8737,8738,8739,8740,8741, // 8742 //13973
****************************************************************************************/
};
@ -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
/***************************************************************************************
* 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,
@ -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
/***************************************************************************************
*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
@ -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
/***************************************************************************************
*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
@ -3168,6 +3167,4 @@ namespace UniversalDetector.Core
return -1;
}
}
}

View File

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

View File

@ -832,23 +832,22 @@ namespace Emby.XmlTv.Classes
public void ProcessNode(XmlReader reader, Action<string> setter, string languageRequired = null, Action<string> allOccurrencesSetter = null)
{
/*
<title lang="es">Homes Under the Hammer - Spanish</title>
<title lang="es">Homes Under the Hammer - Spanish 2</title>
<title lang="en">Homes Under the Hammer - English</title>
<title lang="en">Homes Under the Hammer - English 2</title>
<title lang="">Homes Under the Hammer - Empty Language</title>
<title lang="">Homes Under the Hammer - Empty Language 2</title>
<title>Homes Under the Hammer - No Language</title>
<title>Homes Under the Hammer - No Language 2</title>
*/
/* <title lang="es">Homes Under the Hammer - Spanish</title>
* <title lang="es">Homes Under the Hammer - Spanish 2</title>
* <title lang="en">Homes Under the Hammer - English</title>
* <title lang="en">Homes Under the Hammer - English 2</title>
* <title lang="">Homes Under the Hammer - Empty Language</title>
* <title lang="">Homes Under the Hammer - Empty Language 2</title>
* <title>Homes Under the Hammer - No Language</title>
* <title>Homes Under the Hammer - No Language 2</title>
*/
/* Expected Behaviour:
- Language = Null Homes Under the Hammer - No Language
- Language = "" Homes Under the Hammer - No Language
- Language = es Homes Under the Hammer - Spanish
- Language = en Homes Under the Hammer - English
*/
/* Expected Behaviour:
* - Language = Null Homes Under the Hammer - No Language
* - Language = "" Homes Under the Hammer - No Language
* - Language = es Homes Under the Hammer - Spanish
* - Language = en Homes Under the Hammer - English
*/
var results = new List<Tuple<string, string>>();
@ -921,23 +920,22 @@ namespace Emby.XmlTv.Classes
public void ProcessMultipleNodes(XmlReader reader, Action<string> setter, string languageRequired = null)
{
/*
<category lang="en">Property - English</category>
<category lang="en">Property - English 2</category>
<category lang="es">Property - Spanish</category>
<category lang="es">Property - Spanish 2</category>
<category lang="">Property - Empty Language</category>
<category lang="">Property - Empty Language 2</category>
<category>Property - No Language</category>
<category>Property - No Language 2</category>
*/
/* <category lang="en">Property - English</category>
* <category lang="en">Property - English 2</category>
* <category lang="es">Property - Spanish</category>
* <category lang="es">Property - Spanish 2</category>
* <category lang="">Property - Empty Language</category>
* <category lang="">Property - Empty Language 2</category>
* <category>Property - No Language</category>
* <category>Property - No Language 2</category>
*/
/* Expected Behaviour:
- Language = Null Property - No Language / Property - No Language 2
- Language = "" Property - Empty Language / Property - Empty Language 2
- Language = es Property - Spanish / Property - Spanish 2
- Language = en Property - English / Property - English 2
*/
/* Expected Behaviour:
* - Language = Null Property - No Language / Property - No Language 2
* - Language = "" Property - Empty Language / Property - Empty Language 2
* - Language = es Property - Spanish / Property - Spanish 2
* - Language = en Property - English / Property - English 2
*/
var currentElementName = reader.Name;
var values = new[] { new { Language = reader.GetAttribute("lang"), Value = reader.ReadElementContentAsString() } }.ToList();

View File

@ -97,12 +97,12 @@ namespace Jellyfin.SocketSharp
}
#if NET_4_0
if (validateRequestNewMode && !checked_form) {
// Setting this before calling the validator prevents
// possible endless recursion
checked_form = true;
ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form);
} else
if (validateRequestNewMode && !checked_form) {
// Setting this before calling the validator prevents
// possible endless recursion
checked_form = true;
ValidateNameValueCollection ("Form", query_string_nvc, RequestValidationSource.Form);
} else
#endif
if (validate_form && !checked_form)
{

View File

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

View File

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

View File

@ -1706,7 +1706,8 @@ namespace MediaBrowser.Controller.MediaEncoding
if (string.Equals(outputVideoCodec, "libvpx", StringComparison.OrdinalIgnoreCase))
{
// per docs:
// -threads number of threads to use for encoding, can't be 0 [auto] with VP8 (recommended value : number of real cores - 1)
// -threads number of threads to use for encoding, can't be 0 [auto] with VP8
// (recommended value : number of real cores - 1)
return Math.Max(Environment.ProcessorCount - 1, 1);
}

View File

@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Net
object GetResult(IRequest requestContext, byte[] content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetResult(IRequest requestContext, Stream content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetResult(IRequest requestContext, string content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetResult(IRequest requestContext, string content, string contentType, IDictionary<string, string> responseHeaders = null);
object GetRedirectResult(string url);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -168,7 +168,7 @@ namespace MediaBrowser.Providers.Movies
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";
internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669";
internal static string ApiKey = "4219e299c89411838049ab0dab19ebd5";
internal static string AcceptHeader = "application/json,image/*";
/// <summary>

View File

@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.Movies
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}";
internal static string ApiKey = "f6bd687ffa63cd282b6ff2c6877f2669";
internal static string ApiKey = "4219e299c89411838049ab0dab19ebd5";
internal static string AcceptHeader = "application/json,image/*";
private readonly ILogger _logger;

View File

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

View File

@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.Music
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 AudioDbArtistProvider(IServerConfigurationManager config, IFileSystem fileSystem, IHttpClient httpClient, IJsonSerializer json)

View File

@ -28,7 +28,7 @@ namespace MediaBrowser.Providers.Music
{
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 readonly CultureInfo _usCulture = new CultureInfo("en-US");

View File

@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.Omdb
list.Add(new RemoteImageInfo
{
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)
{
const string url = "https://www.omdbapi.com?apikey=fe53f97e";
const string url = "https://www.omdbapi.com?apikey=2c9d9507";
if (string.IsNullOrWhiteSpace(query))
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,23 +34,22 @@ using System.Threading.Tasks;
namespace Mono.Nat
{
public abstract class AbstractNatDevice : INatDevice
{
private DateTime lastSeen;
public abstract class AbstractNatDevice : INatDevice
{
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
{
get { return lastSeen; }
set { lastSeen = value; }
}
public abstract Task CreatePortMap(Mapping mapping);
}
public abstract Task CreatePortMap(Mapping mapping);
}
}

View File

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

View File

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

View File

@ -34,12 +34,12 @@ using System.Threading.Tasks;
namespace Mono.Nat
{
public interface INatDevice
{
Task CreatePortMap (Mapping mapping);
public interface INatDevice
{
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
{
public class Mapping
{
public class Mapping
{
private string description;
private DateTime expiration;
private int lifetime;
private int privatePort;
private Protocol protocol;
private int publicPort;
private Protocol protocol;
private int publicPort;
public Mapping(Protocol protocol, int privatePort, int publicPort)
: this (protocol, privatePort, publicPort, 0)
{
}
public Mapping(Protocol protocol, int privatePort, int publicPort, int lifetime)
{
this.protocol = protocol;
this.privatePort = privatePort;
this.publicPort = publicPort;
this.lifetime = lifetime;
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;
if (lifetime == int.MaxValue)
this.expiration = DateTime.MaxValue;
else if (lifetime == 0)
this.expiration = DateTime.Now;
else
this.expiration = DateTime.Now.AddSeconds (lifetime);
}
if (lifetime == int.MaxValue)
this.expiration = DateTime.MaxValue;
else if (lifetime == 0)
this.expiration = DateTime.Now;
else
this.expiration = DateTime.Now.AddSeconds (lifetime);
}
public string Description
{
@ -67,57 +65,57 @@ namespace Mono.Nat
set { description = value; }
}
public Protocol Protocol
{
get { return protocol; }
internal set { protocol = value; }
}
public Protocol Protocol
{
get { return protocol; }
internal set { protocol = value; }
}
public int PrivatePort
{
get { return privatePort; }
internal set { privatePort = value; }
}
public int PrivatePort
{
get { return privatePort; }
internal set { privatePort = value; }
}
public int PublicPort
{
get { return publicPort; }
internal set { publicPort = value; }
}
public int PublicPort
{
get { return publicPort; }
internal set { publicPort = value; }
}
public int Lifetime
{
get { return lifetime; }
internal set { lifetime = value; }
}
public int Lifetime
{
get { return lifetime; }
internal set { lifetime = value; }
}
public DateTime Expiration
{
get { return expiration; }
internal set { expiration = value; }
}
public DateTime Expiration
{
get { return expiration; }
internal set { expiration = value; }
}
public bool IsExpired ()
{
return expiration < DateTime.Now;
}
public bool IsExpired()
{
return expiration < DateTime.Now;
}
public override bool Equals (object obj)
{
Mapping other = obj as Mapping;
return other == null ? false : this.protocol == other.protocol &&
this.privatePort == other.privatePort && this.publicPort == other.publicPort;
}
public override bool Equals(object obj)
{
Mapping other = obj as Mapping;
return other == null ? false : this.protocol == other.protocol &&
this.privatePort == other.privatePort && this.publicPort == other.publicPort;
}
public override int GetHashCode()
{
return this.protocol.GetHashCode() ^ this.privatePort.GetHashCode() ^ this.publicPort.GetHashCode();
}
public override int 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}",
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
{
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 OperationCodeUdp = (byte)1;
public const byte OperationCodeTcp = (byte)2;
public const byte OperationCode = (byte)0;
public const byte OperationCodeUdp = (byte)1;
public const byte OperationCodeTcp = (byte)2;
public const byte ServerNoop = (byte)128;
public const int ClientPort = 5350;
public const int ServerPort = 5351;
public const int ClientPort = 5350;
public const int ServerPort = 5351;
public const int RetryDelay = 250;
public const int RetryAttempts = 9;
public const int RetryDelay = 250;
public const int RetryAttempts = 9;
public const int RecommendedLeaseTime = 60 * 60;
public const int DefaultLeaseTime = RecommendedLeaseTime;
public const int RecommendedLeaseTime = 60 * 60;
public const int DefaultLeaseTime = RecommendedLeaseTime;
public const short ResultCodeSuccess = 0;
public const short ResultCodeUnsupportedVersion = 1;
public const short ResultCodeNotAuthorized = 2;
public const short ResultCodeNetworkFailure = 3;
public const short ResultCodeOutOfResources = 4;
public const short ResultCodeUnsupportedOperationCode = 5;
}
public const short ResultCodeSuccess = 0;
public const short ResultCodeUnsupportedVersion = 1;
public const short ResultCodeNotAuthorized = 2;
public const short ResultCodeNetworkFailure = 3;
public const short ResultCodeOutOfResources = 4;
public const short ResultCodeUnsupportedOperationCode = 5;
}
}

View File

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

View File

@ -58,8 +58,8 @@ namespace Mono.Nat
}
public void Search()
{
}
{
}
public async Task Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint)
{
@ -71,15 +71,15 @@ namespace Mono.Nat
try
{
/* For UPnP Port Mapping we need ot find either WANPPPConnection or WANIPConnection.
Any other device type is no good to us for this purpose. See the IGP overview paper
page 5 for an overview of device types and their hierarchy.
http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */
* Any other device type is no good to us for this purpose. See the IGP overview paper
* page 5 for an overview of device types and their hierarchy.
* http://upnp.org/specs/gw/UPnP-gw-InternetGatewayDevice-v1-Device.pdf */
/* TODO: Currently we are assuming version 1 of the protocol. We should figure out which
version it is and apply the correct URN. */
* version it is and apply the correct URN. */
/* Some routers don't correctly implement the version ID on the URN, so we only search for the type
prefix. */
* prefix. */
// We have an internet gateway device now
UpnpNatDevice d = new UpnpNatDevice(localAddress, deviceInfo, endpoint, string.Empty, _logger, _httpClient);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 (selector == null) throw new ArgumentNullException(nameof(selector));
return !source.Any() ? source :
source.Concat(
source
.SelectMany(i => selector(i).EmptyIfNull())
.SelectManyRecursive(selector)
);
}
return !source.Any() ? source :
source.Concat(
source
.SelectMany(i => selector(i).EmptyIfNull())
.SelectManyRecursive(selector)
);
}
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
}
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -538,9 +538,9 @@ namespace Rssdp.Infrastructure
//According to SSDP/UPnP spec, ignore message if missing these headers.
// Edit: But some devices do it anyway
//if (!e.Message.Headers.Contains("MX"))
// WriteTrace("Ignoring search request - missing MX header.");
// WriteTrace("Ignoring search request - missing MX header.");
//else if (!e.Message.Headers.Contains("MAN"))
// WriteTrace("Ignoring search request - missing MAN header.");
// WriteTrace("Ignoring search request - missing MAN header.");
//else
ProcessSearchRequest(GetFirstHeaderValue(e.Message.Headers, "MX"), GetFirstHeaderValue(e.Message.Headers, "ST"), e.ReceivedFrom, e.LocalIpAddress, CancellationToken.None);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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