Skip to content
Browse files

Added MTN based frame grabber plugin. At last our thumbnails will not…

… suck ...

git-svn-id: https://videobrowser.googlecode.com/svn/trunk@1090 096cc86f-8a4c-0410-9b85-8b5e0eee1c45
  • Loading branch information...
1 parent 7d9d068 commit eeb834a36e6c666b5008e3afd3ac3c0f26804bdd sam.saffron committed May 13, 2009
Showing with 20,635 additions and 46 deletions.
  1. +14 −13 FrameGrabProvider/FrameGrabProvider.cs
  2. +10 −4 FrameGrabProvider/GrabImage.cs
  3. +24 −0 MediaBrowser.sln
  4. +27 −29 MediaBrowser/Library/Extensions/StreamExtensions.cs
  5. +34 −0 MtnFrameGrabProvider/FrameGrabProvider.cs
  6. +20 −0 MtnFrameGrabProvider/LICENSE.TXT
  7. +119 −0 MtnFrameGrabProvider/MtnFrameGrabProvider.csproj
  8. +39 −0 MtnFrameGrabProvider/MtnGrabImage.cs
  9. +63 −0 MtnFrameGrabProvider/Plugin.cs
  10. +36 −0 MtnFrameGrabProvider/Properties/AssemblyInfo.cs
  11. +237 −0 MtnFrameGrabProvider/SharpZipLib/Checksums/Adler32.cs
  12. +223 −0 MtnFrameGrabProvider/SharpZipLib/Checksums/CRC32.cs
  13. +93 −0 MtnFrameGrabProvider/SharpZipLib/Checksums/IChecksum.cs
  14. +208 −0 MtnFrameGrabProvider/SharpZipLib/Checksums/StrangeCRC.cs
  15. +532 −0 MtnFrameGrabProvider/SharpZipLib/Core/FileSystemScanner.cs
  16. +57 −0 MtnFrameGrabProvider/SharpZipLib/Core/INameTransform.cs
  17. +52 −0 MtnFrameGrabProvider/SharpZipLib/Core/IScanFilter.cs
  18. +285 −0 MtnFrameGrabProvider/SharpZipLib/Core/NameFilter.cs
  19. +334 −0 MtnFrameGrabProvider/SharpZipLib/Core/PathFilter.cs
  20. +246 −0 MtnFrameGrabProvider/SharpZipLib/Core/StreamUtils.cs
  21. +96 −0 MtnFrameGrabProvider/SharpZipLib/Core/WindowsPathUtils.cs
  22. +498 −0 MtnFrameGrabProvider/SharpZipLib/Encryption/PkzipClassic.cs
  23. +94 −0 MtnFrameGrabProvider/SharpZipLib/SharpZipBaseException.cs
  24. +557 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/Deflater.cs
  25. +186 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/DeflaterConstants.cs
  26. +869 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/DeflaterEngine.cs
  27. +908 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/DeflaterHuffman.cs
  28. +57 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/DeflaterPending.cs
  29. +864 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/Inflater.cs
  30. +215 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/InflaterDynHeader.cs
  31. +232 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs
  32. +295 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/PendingBuffer.cs
  33. +556 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs
  34. +728 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs
  35. +235 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/Streams/OutputWindow.cs
  36. +297 −0 MtnFrameGrabProvider/SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs
  37. +693 −0 MtnFrameGrabProvider/SharpZipLib/Zip/FastZip.cs
  38. +84 −0 MtnFrameGrabProvider/SharpZipLib/Zip/IEntryFactory.cs
  39. +272 −0 MtnFrameGrabProvider/SharpZipLib/Zip/WindowsNameTransform.cs
  40. +624 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipConstants.cs
  41. +1,128 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipEntry.cs
  42. +413 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipEntryFactory.cs
  43. +94 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipException.cs
  44. +984 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipExtraData.cs
  45. +4,447 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipFile.cs
  46. +623 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipHelperStream.cs
  47. +658 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipInputStream.cs
  48. +269 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipNameTransform.cs
  49. +818 −0 MtnFrameGrabProvider/SharpZipLib/Zip/ZipOutputStream.cs
  50. +51 −0 MtnFrameGrabProvider/ThumbCreator.cs
  51. BIN MtnFrameGrabProvider/mtn.zip
  52. +36 −0 TestMtnFrameGrabProvider/Properties/AssemblyInfo.cs
  53. +77 −0 TestMtnFrameGrabProvider/TestMtnFrameGrabProvider.csproj
  54. +24 −0 TestMtnFrameGrabProvider/Tester.cs
View
27 FrameGrabProvider/FrameGrabProvider.cs
@@ -5,29 +5,30 @@
using MediaBrowser.Library.Entities;
using MediaBrowser.Library.Providers.Attributes;
using MediaBrowser.Library.Providers;
+using MediaBrowser.Library;
-namespace FrameGrabProvider
-{
+namespace FrameGrabProvider {
// we mark this as slow, so we ensure it only runs at the end of the chain
[SlowProvider]
[SupportedType(typeof(Video))]
- class FrameGrabProvider : BaseMetadataProvider
- {
+ class FrameGrabProvider : BaseMetadataProvider {
+ static MediaType[] supportedMediaTypes = new MediaType[] { MediaType.Avi, MediaType.Mkv, MediaType.Mpg, MediaType.Unknown };
- public override void Fetch()
- {
- var video = Item as Video;
+ Video Video { get { return (Video)Item; } }
- string path = video.VideoFiles.First();
- if (!path.ToLower().StartsWith("http")) {
- Item.PrimaryImagePath = "grab://" + path;
+ bool Supported {
+ get {
+ return supportedMediaTypes.Contains(Video.MediaType) && !Video.VideoFiles.First().ToLower().StartsWith("http");
}
}
- public override bool NeedsRefresh()
- {
- return (Item.PrimaryImagePath == null);
+ public override void Fetch() {
+ Item.PrimaryImagePath = "grab://" + Video.VideoFiles.First();
+ }
+
+ public override bool NeedsRefresh() {
+ return Item.PrimaryImagePath == null && Supported;
}
}
}
View
14 FrameGrabProvider/GrabImage.cs
@@ -21,13 +21,19 @@ class GrabImage : LibraryImage {
}
// path without grab://
- string video = this.Path.Substring(7);
+ string video = this.Path.Substring(7);
+
+ Plugin.Logger.ReportInfo("Trying to extract thumbnail for " + video);
+
+ if (ThumbCreator.CreateThumb(video, LocalFilename, 0.2)) {
+ return LocalFilename;
+ } else {
+ Plugin.Logger.ReportWarning("Failed to grab thumbnail for " + video);
+ return null;
+ }
- ThumbCreator.CreateThumb(video, LocalFilename, 0.2);
- return LocalFilename;
}
- return null;
}
}
}
View
24 MediaBrowser.sln
@@ -26,6 +26,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaInfoProvider", "MediaI
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FrameGrabProvider", "FrameGrabProvider\FrameGrabProvider.csproj", "{7B7E7D65-5E0C-42E3-93F1-CA7375DA2130}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MtnFrameGrabProvider", "MtnFrameGrabProvider\MtnFrameGrabProvider.csproj", "{369F0855-6162-4D4E-BA56-26C50308FBE2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestMtnFrameGrabProvider", "TestMtnFrameGrabProvider\TestMtnFrameGrabProvider.csproj", "{20333180-4E46-446B-81AC-5C9E8A2CE493}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -136,6 +140,26 @@ Global
{7B7E7D65-5E0C-42E3-93F1-CA7375DA2130}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{7B7E7D65-5E0C-42E3-93F1-CA7375DA2130}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{7B7E7D65-5E0C-42E3-93F1-CA7375DA2130}.Release|x86.ActiveCfg = Release|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {369F0855-6162-4D4E-BA56-26C50308FBE2}.Release|x86.ActiveCfg = Release|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Release|Any CPU.Build.0 = Release|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {20333180-4E46-446B-81AC-5C9E8A2CE493}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
View
56 MediaBrowser/Library/Extensions/StreamExtensions.cs
@@ -13,40 +13,38 @@
namespace MediaBrowser.Library.Extensions {
public static class StreamExtensions {
+
+
public static byte[] ReadAllBytes(this Stream source) {
- long originalPosition = source.Position;
- source.Position = 0;
-
- try {
- byte[] readBuffer = new byte[4096];
-
- int totalBytesRead = 0;
- int bytesRead = 0;
-
- while ((bytesRead = source.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) {
- totalBytesRead += bytesRead;
-
- if (totalBytesRead == readBuffer.Length) {
- int nextByte = source.ReadByte();
- if (nextByte != -1) {
- byte[] temp = new byte[readBuffer.Length * 2];
- Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
- Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
- readBuffer = temp;
- totalBytesRead++;
- }
+
+
+ byte[] readBuffer = new byte[4096];
+
+ int totalBytesRead = 0;
+ int bytesRead = 0;
+
+ while ((bytesRead = source.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0) {
+ totalBytesRead += bytesRead;
+
+ if (totalBytesRead == readBuffer.Length) {
+ int nextByte = source.ReadByte();
+ if (nextByte != -1) {
+ byte[] temp = new byte[readBuffer.Length * 2];
+ Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
+ Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
+ readBuffer = temp;
+ totalBytesRead++;
}
}
+ }
- byte[] buffer = readBuffer;
- if (readBuffer.Length != totalBytesRead) {
- buffer = new byte[totalBytesRead];
- Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
- }
- return buffer;
- } finally {
- source.Position = originalPosition;
+ byte[] buffer = readBuffer;
+ if (readBuffer.Length != totalBytesRead) {
+ buffer = new byte[totalBytesRead];
+ Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
}
+ return buffer;
+
}
}
}
View
34 MtnFrameGrabProvider/FrameGrabProvider.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Linq;
+using MediaBrowser.Library.Entities;
+using MediaBrowser.Library.Providers.Attributes;
+using MediaBrowser.Library.Providers;
+using MediaBrowser.Library;
+
+
+namespace MtnFrameGrabProvider {
+ // we mark this as slow, so we ensure it only runs at the end of the chain
+ [SlowProvider]
+ [SupportedType(typeof(Video))]
+ class FrameGrabProvider : BaseMetadataProvider {
+ static MediaType[] supportedMediaTypes = new MediaType[] { MediaType.Avi, MediaType.Mkv, MediaType.Mpg, MediaType.Unknown };
+
+ Video Video { get { return (Video)Item; } }
+
+ bool Supported {
+ get {
+ return supportedMediaTypes.Contains(Video.MediaType) && !Video.VideoFiles.First().ToLower().StartsWith("http");
+ }
+ }
+
+ public override void Fetch() {
+ Item.PrimaryImagePath = "mtngrab://" + Video.VideoFiles.First();
+ }
+
+ public override bool NeedsRefresh() {
+ return Item.PrimaryImagePath == null && Supported;
+ }
+ }
+}
View
20 MtnFrameGrabProvider/LICENSE.TXT
@@ -0,0 +1,20 @@
+This is light wrapper over the GPL MTN project
+
+Read all about this excellent library at: http://moviethumbnail.sourceforge.net/
+For deployment purposes we are using the SharpZipLib, read all about it at: http://www.icsharpcode.net/OpenSource/SharpZipLib/
+
+Copyright (C) 2009 Sam Saffron
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
View
119 MtnFrameGrabProvider/MtnFrameGrabProvider.csproj
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{369F0855-6162-4D4E-BA56-26C50308FBE2}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>MtnFrameGrabProvider</RootNamespace>
+ <AssemblyName>MtnFrameGrabProvider</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="WindowsBase">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="FrameGrabProvider.cs" />
+ <Compile Include="MtnGrabImage.cs" />
+ <Compile Include="Plugin.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="SharpZipLib\Checksums\Adler32.cs" />
+ <Compile Include="SharpZipLib\Checksums\CRC32.cs" />
+ <Compile Include="SharpZipLib\Checksums\IChecksum.cs" />
+ <Compile Include="SharpZipLib\Checksums\StrangeCRC.cs" />
+ <Compile Include="SharpZipLib\Core\FileSystemScanner.cs" />
+ <Compile Include="SharpZipLib\Core\INameTransform.cs" />
+ <Compile Include="SharpZipLib\Core\IScanFilter.cs" />
+ <Compile Include="SharpZipLib\Core\NameFilter.cs" />
+ <Compile Include="SharpZipLib\Core\PathFilter.cs" />
+ <Compile Include="SharpZipLib\Core\StreamUtils.cs" />
+ <Compile Include="SharpZipLib\Core\WindowsPathUtils.cs" />
+ <Compile Include="SharpZipLib\Encryption\PkzipClassic.cs" />
+ <Compile Include="SharpZipLib\SharpZipBaseException.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\Deflater.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\DeflaterConstants.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\DeflaterEngine.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\DeflaterHuffman.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\DeflaterPending.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\Inflater.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\InflaterDynHeader.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\InflaterHuffmanTree.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\PendingBuffer.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\Streams\DeflaterOutputStream.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\Streams\InflaterInputStream.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\Streams\OutputWindow.cs" />
+ <Compile Include="SharpZipLib\Zip\Compression\Streams\StreamManipulator.cs" />
+ <Compile Include="SharpZipLib\Zip\FastZip.cs" />
+ <Compile Include="SharpZipLib\Zip\IEntryFactory.cs" />
+ <Compile Include="SharpZipLib\Zip\WindowsNameTransform.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipConstants.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipEntry.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipEntryFactory.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipException.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipExtraData.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipFile.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipHelperStream.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipInputStream.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipNameTransform.cs" />
+ <Compile Include="SharpZipLib\Zip\ZipOutputStream.cs" />
+ <Compile Include="ThumbCreator.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="mtn.zip" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="LICENSE.TXT" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\MediaBrowser\MediaBrowser.csproj">
+ <Project>{C6B27E5F-3D83-4D71-85B9-AF83C8392721}</Project>
+ <Name>MediaBrowser</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <PropertyGroup>
+ <PostBuildEvent>copy "$(TargetPath)" C:\ProgramData\MediaBrowser\Plugins\$(TargetFileName)</PostBuildEvent>
+ </PropertyGroup>
+</Project>
View
39 MtnFrameGrabProvider/MtnGrabImage.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MediaBrowser.Library.ImageManagement;
+using System.IO;
+
+namespace MtnFrameGrabProvider {
+ class GrabImage : LibraryImage {
+
+ protected override string LocalFilename {
+ get {
+ return System.IO.Path.Combine(cachePath, Id.ToString() + ".jpg");
+ }
+ }
+
+ public override string GetLocalImagePath() {
+ lock (Lock) {
+ if (File.Exists(LocalFilename)) {
+ return LocalFilename;
+ }
+
+ // path without mtngrab://
+ string video = this.Path.Substring(10);
+
+ Plugin.Logger.ReportInfo("Trying to extract mtn thumbnail for " + video);
+
+ if (ThumbCreator.CreateThumb(video, LocalFilename, 600)) {
+ return LocalFilename;
+ } else {
+ Plugin.Logger.ReportWarning("Failed to grab mtn thumbnail for " + video);
+ return null;
+ }
+
+ }
+
+ }
+ }
+}
View
63 MtnFrameGrabProvider/Plugin.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using MediaBrowser.Library;
+using System.IO;
+using MediaBrowser.Library.Configuration;
+using System.Reflection;
+using MediaBrowser.Library.Plugins;
+using MediaBrowser.Library.Logging;
+using ICSharpCode.SharpZipLib.Zip;
+using MediaBrowser.Library.Extensions;
+
+namespace MtnFrameGrabProvider {
+ public class Plugin : IPlugin {
+
+ public static ILogger Logger { get; private set; }
+
+ public static readonly string MtnPath = Path.Combine(ApplicationPaths.AppPluginPath, "mtn");
+ public static readonly string MtnExe = Path.Combine(MtnPath, "mtn.exe");
+ public static readonly string FrameGrabsPath = Path.Combine(MtnPath, "FrameGrabs");
+
+ public void Init(LibraryConfig config) {
+
+ EnsureMtnIsExtracted();
+
+ Logger = config.Logger;
+
+ config.Providers.Add(new MetadataProviderFactory(typeof(FrameGrabProvider)));
+
+ config.ImageResolvers.Add(path =>
+ {
+ if (path.ToLower().StartsWith("mtn")) {
+ return new GrabImage();
+ }
+ return null;
+ });
+ }
+
+ public static void EnsureMtnIsExtracted() {
+
+ if (!Directory.Exists(MtnPath)) {
+ Directory.CreateDirectory(MtnPath);
+ Directory.CreateDirectory(FrameGrabsPath);
+
+
+ string name = "MtnFrameGrabProvider.mtn.zip";
+ var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
+
+ using (var zip = new ZipInputStream(stream)) {
+
+ ZipEntry entry;
+ while ((entry = zip.GetNextEntry()) != null) {
+ string destination = Path.Combine(MtnPath, entry.Name);
+ File.WriteAllBytes(destination, zip.ReadAllBytes());
+ }
+ }
+ }
+ }
+
+
+ }
+}
View
36 MtnFrameGrabProvider/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MtnFrameGrabProvider")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("MtnFrameGrabProvider")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("06242497-d32e-490f-80c6-7597d7774426")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
View
237 MtnFrameGrabProvider/SharpZipLib/Checksums/Adler32.cs
@@ -0,0 +1,237 @@
+// Adler32.cs - Computes Adler32 data checksum of a data stream
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace ICSharpCode.SharpZipLib.Checksums
+{
+
+ /// <summary>
+ /// Computes Adler32 checksum for a stream of data. An Adler32
+ /// checksum is not as reliable as a CRC32 checksum, but a lot faster to
+ /// compute.
+ ///
+ /// The specification for Adler32 may be found in RFC 1950.
+ /// ZLIB Compressed Data Format Specification version 3.3)
+ ///
+ ///
+ /// From that document:
+ ///
+ /// "ADLER32 (Adler-32 checksum)
+ /// This contains a checksum value of the uncompressed data
+ /// (excluding any dictionary data) computed according to Adler-32
+ /// algorithm. This algorithm is a 32-bit extension and improvement
+ /// of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+ /// standard.
+ ///
+ /// Adler-32 is composed of two sums accumulated per byte: s1 is
+ /// the sum of all bytes, s2 is the sum of all s1 values. Both sums
+ /// are done modulo 65521. s1 is initialized to 1, s2 to zero. The
+ /// Adler-32 checksum is stored as s2*65536 + s1 in most-
+ /// significant-byte first (network) order."
+ ///
+ /// "8.2. The Adler-32 algorithm
+ ///
+ /// The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+ /// still provides an extremely low probability of undetected errors.
+ ///
+ /// The modulo on unsigned long accumulators can be delayed for 5552
+ /// bytes, so the modulo operation time is negligible. If the bytes
+ /// are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+ /// and order sensitive, unlike the first sum, which is just a
+ /// checksum. That 65521 is prime is important to avoid a possible
+ /// large class of two-byte errors that leave the check unchanged.
+ /// (The Fletcher checksum uses 255, which is not prime and which also
+ /// makes the Fletcher check insensitive to single byte changes 0 -
+ /// 255.)
+ ///
+ /// The sum s1 is initialized to 1 instead of zero to make the length
+ /// of the sequence part of s2, so that the length does not have to be
+ /// checked separately. (Any sequence of zeroes has a Fletcher
+ /// checksum of zero.)"
+ /// </summary>
+ /// <see cref="ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream"/>
+ /// <see cref="ICSharpCode.SharpZipLib.Zip.Compression.Streams.DeflaterOutputStream"/>
+ public sealed class Adler32 : IChecksum
+ {
+ /// <summary>
+ /// largest prime smaller than 65536
+ /// </summary>
+ const uint BASE = 65521;
+
+ /// <summary>
+ /// Returns the Adler32 data checksum computed so far.
+ /// </summary>
+ public long Value {
+ get {
+ return checksum;
+ }
+ }
+
+ /// <summary>
+ /// Creates a new instance of the Adler32 class.
+ /// The checksum starts off with a value of 1.
+ /// </summary>
+ public Adler32()
+ {
+ Reset();
+ }
+
+ /// <summary>
+ /// Resets the Adler32 checksum to the initial value.
+ /// </summary>
+ public void Reset()
+ {
+ checksum = 1;
+ }
+
+ /// <summary>
+ /// Updates the checksum with a byte value.
+ /// </summary>
+ /// <param name="value">
+ /// The data value to add. The high byte of the int is ignored.
+ /// </param>
+ public void Update(int value)
+ {
+ // We could make a length 1 byte array and call update again, but I
+ // would rather not have that overhead
+ uint s1 = checksum & 0xFFFF;
+ uint s2 = checksum >> 16;
+
+ s1 = (s1 + ((uint)value & 0xFF)) % BASE;
+ s2 = (s1 + s2) % BASE;
+
+ checksum = (s2 << 16) + s1;
+ }
+
+ /// <summary>
+ /// Updates the checksum with an array of bytes.
+ /// </summary>
+ /// <param name="buffer">
+ /// The source of the data to update with.
+ /// </param>
+ public void Update(byte[] buffer)
+ {
+ if ( buffer == null ) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ Update(buffer, 0, buffer.Length);
+ }
+
+ /// <summary>
+ /// Updates the checksum with the bytes taken from the array.
+ /// </summary>
+ /// <param name="buffer">
+ /// an array of bytes
+ /// </param>
+ /// <param name="offset">
+ /// the start of the data used for this update
+ /// </param>
+ /// <param name="count">
+ /// the number of bytes to use for this update
+ /// </param>
+ public void Update(byte[] buffer, int offset, int count)
+ {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ if (offset < 0) {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("offset");
+#else
+ throw new ArgumentOutOfRangeException("offset", "cannot be negative");
+#endif
+ }
+
+ if ( count < 0 )
+ {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("count");
+#else
+ throw new ArgumentOutOfRangeException("count", "cannot be negative");
+#endif
+ }
+
+ if (offset >= buffer.Length)
+ {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("offset");
+#else
+ throw new ArgumentOutOfRangeException("offset", "not a valid index into buffer");
+#endif
+ }
+
+ if (offset + count > buffer.Length)
+ {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("count");
+#else
+ throw new ArgumentOutOfRangeException("count", "exceeds buffer size");
+#endif
+ }
+
+ //(By Per Bothner)
+ uint s1 = checksum & 0xFFFF;
+ uint s2 = checksum >> 16;
+
+ while (count > 0) {
+ // We can defer the modulo operation:
+ // s1 maximally grows from 65521 to 65521 + 255 * 3800
+ // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
+ int n = 3800;
+ if (n > count) {
+ n = count;
+ }
+ count -= n;
+ while (--n >= 0) {
+ s1 = s1 + (uint)(buffer[offset++] & 0xff);
+ s2 = s2 + s1;
+ }
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+
+ checksum = (s2 << 16) | s1;
+ }
+
+ #region Instance Fields
+ uint checksum;
+ #endregion
+ }
+}
View
223 MtnFrameGrabProvider/SharpZipLib/Checksums/CRC32.cs
@@ -0,0 +1,223 @@
+// CRC32.cs - Computes CRC32 data checksum of a data stream
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace ICSharpCode.SharpZipLib.Checksums
+{
+
+ /// <summary>
+ /// Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+ /// x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+ ///
+ /// Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ /// with the lowest powers in the most significant bit. Then adding polynomials
+ /// is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ /// one. If we call the above polynomial p, and represent a byte as the
+ /// polynomial q, also with the lowest power in the most significant bit (so the
+ /// byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ /// where a mod b means the remainder after dividing a by b.
+ ///
+ /// This calculation is done using the shift-register method of multiplying and
+ /// taking the remainder. The register is initialized to zero, and for each
+ /// incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ /// x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ /// x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ /// out is a one). We start with the highest power (least significant bit) of
+ /// q and repeat for all eight bits of q.
+ ///
+ /// The table is simply the CRC of all possible eight bit values. This is all
+ /// the information needed to generate CRC's on data a byte at a time for all
+ /// combinations of CRC register values and incoming bytes.
+ /// </summary>
+ public sealed class Crc32 : IChecksum
+ {
+ const uint CrcSeed = 0xFFFFFFFF;
+
+ readonly static uint[] CrcTable = new uint[] {
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,
+ 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
+ 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,
+ 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,
+ 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
+ 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
+ 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
+ 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
+ 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,
+ 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,
+ 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
+ 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,
+ 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
+ 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
+ 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
+ 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
+ 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
+ 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,
+ 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,
+ 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
+ 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
+ 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,
+ 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
+ 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,
+ 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,
+ 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
+ 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
+ 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,
+ 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
+ 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,
+ 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
+ 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
+ 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,
+ 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
+ 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
+ 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,
+ 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
+ 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
+ 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
+ 0x2D02EF8D
+ };
+
+ internal static uint ComputeCrc32(uint oldCrc, byte value)
+ {
+ return (uint)(Crc32.CrcTable[(oldCrc ^ value) & 0xFF] ^ (oldCrc >> 8));
+ }
+
+ /// <summary>
+ /// The crc data checksum so far.
+ /// </summary>
+ uint crc;
+
+ /// <summary>
+ /// Returns the CRC32 data checksum computed so far.
+ /// </summary>
+ public long Value {
+ get {
+ return (long)crc;
+ }
+ set {
+ crc = (uint)value;
+ }
+ }
+
+ /// <summary>
+ /// Resets the CRC32 data checksum as if no update was ever called.
+ /// </summary>
+ public void Reset()
+ {
+ crc = 0;
+ }
+
+ /// <summary>
+ /// Updates the checksum with the int bval.
+ /// </summary>
+ /// <param name = "value">
+ /// the byte is taken as the lower 8 bits of value
+ /// </param>
+ public void Update(int value)
+ {
+ crc ^= CrcSeed;
+ crc = CrcTable[(crc ^ value) & 0xFF] ^ (crc >> 8);
+ crc ^= CrcSeed;
+ }
+
+ /// <summary>
+ /// Updates the checksum with the bytes taken from the array.
+ /// </summary>
+ /// <param name="buffer">
+ /// buffer an array of bytes
+ /// </param>
+ public void Update(byte[] buffer)
+ {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ Update(buffer, 0, buffer.Length);
+ }
+
+ /// <summary>
+ /// Adds the byte array to the data checksum.
+ /// </summary>
+ /// <param name = "buffer">
+ /// The buffer which contains the data
+ /// </param>
+ /// <param name = "offset">
+ /// The offset in the buffer where the data starts
+ /// </param>
+ /// <param name = "count">
+ /// The number of data bytes to update the CRC with.
+ /// </param>
+ public void Update(byte[] buffer, int offset, int count)
+ {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ if ( count < 0 ) {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("count");
+#else
+ throw new ArgumentOutOfRangeException("count", "Count cannot be less than zero");
+#endif
+ }
+
+ if (offset < 0 || offset + count > buffer.Length) {
+ throw new ArgumentOutOfRangeException("offset");
+ }
+
+ crc ^= CrcSeed;
+
+ while (--count >= 0) {
+ crc = CrcTable[(crc ^ buffer[offset++]) & 0xFF] ^ (crc >> 8);
+ }
+
+ crc ^= CrcSeed;
+ }
+ }
+}
View
93 MtnFrameGrabProvider/SharpZipLib/Checksums/IChecksum.cs
@@ -0,0 +1,93 @@
+// IChecksum.cs - Interface to compute a data checksum
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+namespace ICSharpCode.SharpZipLib.Checksums
+{
+
+ /// <summary>
+ /// Interface to compute a data checksum used by checked input/output streams.
+ /// A data checksum can be updated by one byte or with a byte array. After each
+ /// update the value of the current checksum can be returned by calling
+ /// <code>getValue</code>. The complete checksum object can also be reset
+ /// so it can be used again with new data.
+ /// </summary>
+ public interface IChecksum
+ {
+ /// <summary>
+ /// Returns the data checksum computed so far.
+ /// </summary>
+ long Value
+ {
+ get;
+ }
+
+ /// <summary>
+ /// Resets the data checksum as if no update was ever called.
+ /// </summary>
+ void Reset();
+
+ /// <summary>
+ /// Adds one byte to the data checksum.
+ /// </summary>
+ /// <param name = "value">
+ /// the data value to add. The high byte of the int is ignored.
+ /// </param>
+ void Update(int value);
+
+ /// <summary>
+ /// Updates the data checksum with the bytes taken from the array.
+ /// </summary>
+ /// <param name="buffer">
+ /// buffer an array of bytes
+ /// </param>
+ void Update(byte[] buffer);
+
+ /// <summary>
+ /// Adds the byte array to the data checksum.
+ /// </summary>
+ /// <param name = "buffer">
+ /// The buffer which contains the data
+ /// </param>
+ /// <param name = "offset">
+ /// The offset in the buffer where the data starts
+ /// </param>
+ /// <param name = "count">
+ /// the number of data bytes to add.
+ /// </param>
+ void Update(byte[] buffer, int offset, int count);
+ }
+}
View
208 MtnFrameGrabProvider/SharpZipLib/Checksums/StrangeCRC.cs
@@ -0,0 +1,208 @@
+// StrangeCRC.cs - computes a crc used in the bziplib
+//
+// Copyright (C) 2001 Mike Krueger
+//
+// This file was translated from java, it was part of the GNU Classpath
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace ICSharpCode.SharpZipLib.Checksums
+{
+ /// <summary>
+ /// Bzip2 checksum algorithm
+ /// </summary>
+ public class StrangeCRC : IChecksum
+ {
+ readonly static uint[] crc32Table = {
+ 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9,
+ 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
+ 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+ 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
+ 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+ 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
+ 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
+ 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
+ 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
+ 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+ 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49,
+ 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+ 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
+ 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
+ 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+ 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
+ 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+ 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
+ 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
+ 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
+ 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
+ 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+ 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
+ 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+ 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
+ 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
+ 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+ 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
+ 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+ 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
+ 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
+ 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
+ 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
+ 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+ 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
+ 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+ 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
+ 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
+ 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+ 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
+ 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+ 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
+ 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
+ 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
+ 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
+ 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+ 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
+ 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+ 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
+ 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
+ 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+ 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
+ };
+
+ int globalCrc;
+
+ /// <summary>
+ /// Initialise a default instance of <see cref="StrangeCRC"></see>
+ /// </summary>
+ public StrangeCRC()
+ {
+ Reset();
+ }
+
+ /// <summary>
+ /// Reset the state of Crc.
+ /// </summary>
+ public void Reset()
+ {
+ globalCrc = -1;
+ }
+
+ /// <summary>
+ /// Get the current Crc value.
+ /// </summary>
+ public long Value {
+ get {
+ return ~globalCrc;
+ }
+ }
+
+ /// <summary>
+ /// Update the Crc value.
+ /// </summary>
+ /// <param name="value">data update is based on</param>
+ public void Update(int value)
+ {
+ int temp = (globalCrc >> 24) ^ value;
+ if (temp < 0) {
+ temp = 256 + temp;
+ }
+ globalCrc = unchecked((int)((globalCrc << 8) ^ crc32Table[temp]));
+ }
+
+ /// <summary>
+ /// Update Crc based on a block of data
+ /// </summary>
+ /// <param name="buffer">The buffer containing data to update the crc with.</param>
+ public void Update(byte[] buffer)
+ {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ Update(buffer, 0, buffer.Length);
+ }
+
+ /// <summary>
+ /// Update Crc based on a portion of a block of data
+ /// </summary>
+ /// <param name="buffer">block of data</param>
+ /// <param name="offset">index of first byte to use</param>
+ /// <param name="count">number of bytes to use</param>
+ public void Update(byte[] buffer, int offset, int count)
+ {
+ if (buffer == null) {
+ throw new ArgumentNullException("buffer");
+ }
+
+ if ( offset < 0 )
+ {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("offset");
+#else
+ throw new ArgumentOutOfRangeException("offset", "cannot be less than zero");
+#endif
+ }
+
+ if ( count < 0 )
+ {
+#if NETCF_1_0
+ throw new ArgumentOutOfRangeException("count");
+#else
+ throw new ArgumentOutOfRangeException("count", "cannot be less than zero");
+#endif
+ }
+
+ if ( offset + count > buffer.Length )
+ {
+ throw new ArgumentOutOfRangeException("count");
+ }
+
+ for (int i = 0; i < count; ++i) {
+ Update(buffer[offset++]);
+ }
+ }
+ }
+}
View
532 MtnFrameGrabProvider/SharpZipLib/Core/FileSystemScanner.cs
@@ -0,0 +1,532 @@
+// FileSystemScanner.cs
+//
+// Copyright 2005 John Reilly
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+
+using System;
+using System.IO;
+
+namespace ICSharpCode.SharpZipLib.Core
+{
+ #region EventArgs
+ /// <summary>
+ /// Event arguments for scanning.
+ /// </summary>
+ public class ScanEventArgs : EventArgs
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialise a new instance of <see cref="ScanEventArgs"/>
+ /// </summary>
+ /// <param name="name">The file or directory name.</param>
+ public ScanEventArgs(string name)
+ {
+ name_ = name;
+ }
+ #endregion
+
+ /// <summary>
+ /// The file or directory name for this event.
+ /// </summary>
+ public string Name
+ {
+ get { return name_; }
+ }
+
+ /// <summary>
+ /// Get set a value indicating if scanning should continue or not.
+ /// </summary>
+ public bool ContinueRunning
+ {
+ get { return continueRunning_; }
+ set { continueRunning_ = value; }
+ }
+
+ #region Instance Fields
+ string name_;
+ bool continueRunning_ = true;
+ #endregion
+ }
+
+ /// <summary>
+ /// Event arguments during processing of a single file or directory.
+ /// </summary>
+ public class ProgressEventArgs : EventArgs
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialise a new instance of <see cref="ScanEventArgs"/>
+ /// </summary>
+ /// <param name="name">The file or directory name if known.</param>
+ /// <param name="processed">The number of bytes processed so far</param>
+ /// <param name="target">The total number of bytes to process, 0 if not known</param>
+ public ProgressEventArgs(string name, long processed, long target)
+ {
+ name_ = name;
+ processed_ = processed;
+ target_ = target;
+ }
+ #endregion
+
+ /// <summary>
+ /// The name for this event if known.
+ /// </summary>
+ public string Name
+ {
+ get { return name_; }
+ }
+
+ /// <summary>
+ /// Get set a value indicating wether scanning should continue or not.
+ /// </summary>
+ public bool ContinueRunning
+ {
+ get { return continueRunning_; }
+ set { continueRunning_ = value; }
+ }
+
+ /// <summary>
+ /// Get a percentage representing how much of the <see cref="Target"></see> has been processed
+ /// </summary>
+ /// <value>0.0 to 100.0 percent; 0 if target is not known.</value>
+ public float PercentComplete
+ {
+ get
+ {
+ if (target_ <= 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return ((float)processed_ / (float)target_) * 100.0f;
+ }
+ }
+ }
+
+ /// <summary>
+ /// The number of bytes processed so far
+ /// </summary>
+ public long Processed
+ {
+ get { return processed_; }
+ }
+
+ /// <summary>
+ /// The number of bytes to process.
+ /// </summary>
+ /// <remarks>Target may be 0 or negative if the value isnt known.</remarks>
+ public long Target
+ {
+ get { return target_; }
+ }
+
+ #region Instance Fields
+ string name_;
+ long processed_;
+ long target_;
+ bool continueRunning_ = true;
+ #endregion
+ }
+
+ /// <summary>
+ /// Event arguments for directories.
+ /// </summary>
+ public class DirectoryEventArgs : ScanEventArgs
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialize an instance of <see cref="DirectoryEventArgs"></see>.
+ /// </summary>
+ /// <param name="name">The name for this directory.</param>
+ /// <param name="hasMatchingFiles">Flag value indicating if any matching files are contained in this directory.</param>
+ public DirectoryEventArgs(string name, bool hasMatchingFiles)
+ : base (name)
+ {
+ hasMatchingFiles_ = hasMatchingFiles;
+ }
+ #endregion
+
+ /// <summary>
+ /// Get a value indicating if the directory contains any matching files or not.
+ /// </summary>
+ public bool HasMatchingFiles
+ {
+ get { return hasMatchingFiles_; }
+ }
+
+ #region Instance Fields
+ bool hasMatchingFiles_;
+ #endregion
+ }
+
+ /// <summary>
+ /// Arguments passed when scan failures are detected.
+ /// </summary>
+ public class ScanFailureEventArgs : EventArgs
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialise a new instance of <see cref="ScanFailureEventArgs"></see>
+ /// </summary>
+ /// <param name="name">The name to apply.</param>
+ /// <param name="e">The exception to use.</param>
+ public ScanFailureEventArgs(string name, Exception e)
+ {
+ name_ = name;
+ exception_ = e;
+ continueRunning_ = true;
+ }
+ #endregion
+
+ /// <summary>
+ /// The applicable name.
+ /// </summary>
+ public string Name
+ {
+ get { return name_; }
+ }
+
+ /// <summary>
+ /// The applicable exception.
+ /// </summary>
+ public Exception Exception
+ {
+ get { return exception_; }
+ }
+
+ /// <summary>
+ /// Get / set a value indicating wether scanning should continue.
+ /// </summary>
+ public bool ContinueRunning
+ {
+ get { return continueRunning_; }
+ set { continueRunning_ = value; }
+ }
+
+ #region Instance Fields
+ string name_;
+ Exception exception_;
+ bool continueRunning_;
+ #endregion
+ }
+
+ #endregion
+
+ #region Delegates
+ /// <summary>
+ /// Delegate invoked before starting to process a directory.
+ /// </summary>
+ public delegate void ProcessDirectoryHandler(object sender, DirectoryEventArgs e);
+
+ /// <summary>
+ /// Delegate invoked before starting to process a file.
+ /// </summary>
+ /// <param name="sender">The source of the event</param>
+ /// <param name="e">The event arguments.</param>
+ public delegate void ProcessFileHandler(object sender, ScanEventArgs e);
+
+ /// <summary>
+ /// Delegate invoked during processing of a file or directory
+ /// </summary>
+ /// <param name="sender">The source of the event</param>
+ /// <param name="e">The event arguments.</param>
+ public delegate void ProgressHandler(object sender, ProgressEventArgs e);
+
+ /// <summary>
+ /// Delegate invoked when a file has been completely processed.
+ /// </summary>
+ /// <param name="sender">The source of the event</param>
+ /// <param name="e">The event arguments.</param>
+ public delegate void CompletedFileHandler(object sender, ScanEventArgs e);
+
+ /// <summary>
+ /// Delegate invoked when a directory failure is detected.
+ /// </summary>
+ /// <param name="sender">The source of the event</param>
+ /// <param name="e">The event arguments.</param>
+ public delegate void DirectoryFailureHandler(object sender, ScanFailureEventArgs e);
+
+ /// <summary>
+ /// Delegate invoked when a file failure is detected.
+ /// </summary>
+ /// <param name="sender">The source of the event</param>
+ /// <param name="e">The event arguments.</param>
+ public delegate void FileFailureHandler(object sender, ScanFailureEventArgs e);
+ #endregion
+
+ /// <summary>
+ /// FileSystemScanner provides facilities scanning of files and directories.
+ /// </summary>
+ public class FileSystemScanner
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialise a new instance of <see cref="FileSystemScanner"></see>
+ /// </summary>
+ /// <param name="filter">The <see cref="PathFilter">file filter</see> to apply when scanning.</param>
+ public FileSystemScanner(string filter)
+ {
+ fileFilter_ = new PathFilter(filter);
+ }
+
+ /// <summary>
+ /// Initialise a new instance of <see cref="FileSystemScanner"></see>
+ /// </summary>
+ /// <param name="fileFilter">The <see cref="PathFilter">file filter</see> to apply.</param>
+ /// <param name="directoryFilter">The <see cref="PathFilter"> directory filter</see> to apply.</param>
+ public FileSystemScanner(string fileFilter, string directoryFilter)
+ {
+ fileFilter_ = new PathFilter(fileFilter);
+ directoryFilter_ = new PathFilter(directoryFilter);
+ }
+
+ /// <summary>
+ /// Initialise a new instance of <see cref="FileSystemScanner"></see>
+ /// </summary>
+ /// <param name="fileFilter">The file <see cref="IScanFilter">filter</see> to apply.</param>
+ public FileSystemScanner(IScanFilter fileFilter)
+ {
+ fileFilter_ = fileFilter;
+ }
+
+ /// <summary>
+ /// Initialise a new instance of <see cref="FileSystemScanner"></see>
+ /// </summary>
+ /// <param name="fileFilter">The file <see cref="IScanFilter">filter</see> to apply.</param>
+ /// <param name="directoryFilter">The directory <see cref="IScanFilter">filter</see> to apply.</param>
+ public FileSystemScanner(IScanFilter fileFilter, IScanFilter directoryFilter)
+ {
+ fileFilter_ = fileFilter;
+ directoryFilter_ = directoryFilter;
+ }
+ #endregion
+
+ #region Delegates
+ /// <summary>
+ /// Delegate to invoke when a directory is processed.
+ /// </summary>
+ public ProcessDirectoryHandler ProcessDirectory;
+
+ /// <summary>
+ /// Delegate to invoke when a file is processed.
+ /// </summary>
+ public ProcessFileHandler ProcessFile;
+
+ /// <summary>
+ /// Delegate to invoke when processing for a file has finished.
+ /// </summary>
+ public CompletedFileHandler CompletedFile;
+
+ /// <summary>
+ /// Delegate to invoke when a directory failure is detected.
+ /// </summary>
+ public DirectoryFailureHandler DirectoryFailure;
+
+ /// <summary>
+ /// Delegate to invoke when a file failure is detected.
+ /// </summary>
+ public FileFailureHandler FileFailure;
+ #endregion
+
+ /// <summary>
+ /// Raise the DirectoryFailure event.
+ /// </summary>
+ /// <param name="directory">The directory name.</param>
+ /// <param name="e">The exception detected.</param>
+ bool OnDirectoryFailure(string directory, Exception e)
+ {
+ DirectoryFailureHandler handler = DirectoryFailure;
+ bool result = (handler != null);
+ if ( result ) {
+ ScanFailureEventArgs args = new ScanFailureEventArgs(directory, e);
+ handler(this, args);
+ alive_ = args.ContinueRunning;
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Raise the FileFailure event.
+ /// </summary>
+ /// <param name="file">The file name.</param>
+ /// <param name="e">The exception detected.</param>
+ bool OnFileFailure(string file, Exception e)
+ {
+ FileFailureHandler handler = FileFailure;
+
+ bool result = (handler != null);
+
+ if ( result ){
+ ScanFailureEventArgs args = new ScanFailureEventArgs(file, e);
+ FileFailure(this, args);
+ alive_ = args.ContinueRunning;
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Raise the ProcessFile event.
+ /// </summary>
+ /// <param name="file">The file name.</param>
+ void OnProcessFile(string file)
+ {
+ ProcessFileHandler handler = ProcessFile;
+
+ if ( handler!= null ) {
+ ScanEventArgs args = new ScanEventArgs(file);
+ handler(this, args);
+ alive_ = args.ContinueRunning;
+ }
+ }
+
+ /// <summary>
+ /// Raise the complete file event
+ /// </summary>
+ /// <param name="file">The file name</param>
+ void OnCompleteFile(string file)
+ {
+ CompletedFileHandler handler = CompletedFile;
+
+ if (handler != null)
+ {
+ ScanEventArgs args = new ScanEventArgs(file);
+ handler(this, args);
+ alive_ = args.ContinueRunning;
+ }
+ }
+
+ /// <summary>
+ /// Raise the ProcessDirectory event.
+ /// </summary>
+ /// <param name="directory">The directory name.</param>
+ /// <param name="hasMatchingFiles">Flag indicating if the directory has matching files.</param>
+ void OnProcessDirectory(string directory, bool hasMatchingFiles)
+ {
+ ProcessDirectoryHandler handler = ProcessDirectory;
+
+ if ( handler != null ) {
+ DirectoryEventArgs args = new DirectoryEventArgs(directory, hasMatchingFiles);
+ handler(this, args);
+ alive_ = args.ContinueRunning;
+ }
+ }
+
+ /// <summary>
+ /// Scan a directory.
+ /// </summary>
+ /// <param name="directory">The base directory to scan.</param>
+ /// <param name="recurse">True to recurse subdirectories, false to scan a single directory.</param>
+ public void Scan(string directory, bool recurse)
+ {
+ alive_ = true;
+ ScanDir(directory, recurse);
+ }
+
+ void ScanDir(string directory, bool recurse)
+ {
+
+ try {
+ string[] names = System.IO.Directory.GetFiles(directory);
+ bool hasMatch = false;
+ for (int fileIndex = 0; fileIndex < names.Length; ++fileIndex) {
+ if ( !fileFilter_.IsMatch(names[fileIndex]) ) {
+ names[fileIndex] = null;
+ } else {
+ hasMatch = true;
+ }
+ }
+
+ OnProcessDirectory(directory, hasMatch);
+
+ if ( alive_ && hasMatch ) {
+ foreach (string fileName in names) {
+ try {
+ if ( fileName != null ) {
+ OnProcessFile(fileName);
+ if ( !alive_ ) {
+ break;
+ }
+ }
+ }
+ catch (Exception e) {
+ if (!OnFileFailure(fileName, e)) {
+ throw;
+ }
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ if (!OnDirectoryFailure(directory, e)) {
+ throw;
+ }
+ }
+
+ if ( alive_ && recurse ) {
+ try {
+ string[] names = System.IO.Directory.GetDirectories(directory);
+ foreach (string fulldir in names) {
+ if ((directoryFilter_ == null) || (directoryFilter_.IsMatch(fulldir))) {
+ ScanDir(fulldir, true);
+ if ( !alive_ ) {
+ break;
+ }
+ }
+ }
+ }
+ catch (Exception e) {
+ if (!OnDirectoryFailure(directory, e)) {
+ throw;
+ }
+ }
+ }
+ }
+
+ #region Instance Fields
+ /// <summary>
+ /// The file filter currently in use.
+ /// </summary>
+ IScanFilter fileFilter_;
+ /// <summary>
+ /// The directory filter currently in use.
+ /// </summary>
+ IScanFilter directoryFilter_;
+ /// <summary>
+ /// Flag indicating if scanning should continue running.
+ /// </summary>
+ bool alive_;
+ #endregion
+ }
+}
View
57 MtnFrameGrabProvider/SharpZipLib/Core/INameTransform.cs
@@ -0,0 +1,57 @@
+// INameTransform.cs
+//
+// Copyright 2005 John Reilly
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+namespace ICSharpCode.SharpZipLib.Core
+{
+ /// <summary>
+ /// INameTransform defines how file system names are transformed for use with archives, or vice versa.
+ /// </summary>
+ public interface INameTransform
+ {
+ /// <summary>
+ /// Given a file name determine the transformed value.
+ /// </summary>
+ /// <param name="name">The name to transform.</param>
+ /// <returns>The transformed file name.</returns>
+ string TransformFile(string name);
+
+ /// <summary>
+ /// Given a directory name determine the transformed value.
+ /// </summary>
+ /// <param name="name">The name to transform.</param>
+ /// <returns>The transformed directory name</returns>
+ string TransformDirectory(string name);
+ }
+}
View
52 MtnFrameGrabProvider/SharpZipLib/Core/IScanFilter.cs
@@ -0,0 +1,52 @@
+// IScanFilter.cs
+//
+// Copyright 2006 John Reilly
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+
+namespace ICSharpCode.SharpZipLib.Core
+{
+ /// <summary>
+ /// Scanning filters support filtering of names.
+ /// </summary>
+ public interface IScanFilter
+ {
+ /// <summary>
+ /// Test a name to see if it 'matches' the filter.
+ /// </summary>
+ /// <param name="name">The name to test.</param>
+ /// <returns>Returns true if the name matches the filter, false if it does not match.</returns>
+ bool IsMatch(string name);
+ }
+}
View
285 MtnFrameGrabProvider/SharpZipLib/Core/NameFilter.cs
@@ -0,0 +1,285 @@
+// NameFilter.cs
+//
+// Copyright 2005 John Reilly
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+
+using System;
+using System.Collections;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace ICSharpCode.SharpZipLib.Core
+{
+ /// <summary>
+ /// NameFilter is a string matching class which allows for both positive and negative
+ /// matching.
+ /// A filter is a sequence of independant <see cref="Regex">regular expressions</see> separated by semi-colons ';'.
+ /// To include a semi-colon it may be quoted as in \;. Each expression can be prefixed by a plus '+' sign or
+ /// a minus '-' sign to denote the expression is intended to include or exclude names.
+ /// If neither a plus or minus sign is found include is the default.
+ /// A given name is tested for inclusion before checking exclusions. Only names matching an include spec
+ /// and not matching an exclude spec are deemed to match the filter.
+ /// An empty filter matches any name.
+ /// </summary>
+ /// <example>The following expression includes all name ending in '.dat' with the exception of 'dummy.dat'
+ /// "+\.dat$;-^dummy\.dat$"
+ /// </example>
+ public class NameFilter : IScanFilter
+ {
+ #region Constructors
+ /// <summary>
+ /// Construct an instance based on the filter expression passed
+ /// </summary>
+ /// <param name="filter">The filter expression.</param>
+ public NameFilter(string filter)
+ {
+ filter_ = filter;
+ inclusions_ = new ArrayList();
+ exclusions_ = new ArrayList();
+ Compile();
+ }
+ #endregion
+
+ /// <summary>
+ /// Test a string to see if it is a valid regular expression.
+ /// </summary>
+ /// <param name="expression">The expression to test.</param>
+ /// <returns>True if expression is a valid <see cref="System.Text.RegularExpressions.Regex"/> false otherwise.</returns>
+ public static bool IsValidExpression(string expression)
+ {
+ bool result = true;
+ try {
+ Regex exp = new Regex(expression, RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ }
+ catch (ArgumentException) {
+ result = false;
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Test an expression to see if it is valid as a filter.
+ /// </summary>
+ /// <param name="toTest">The filter expression to test.</param>
+ /// <returns>True if the expression is valid, false otherwise.</returns>
+ public static bool IsValidFilterExpression(string toTest)
+ {
+ if ( toTest == null ) {
+ throw new ArgumentNullException("toTest");
+ }
+
+ bool result = true;
+
+ try {
+ string[] items = SplitQuoted(toTest);
+ for (int i = 0; i < items.Length; ++i) {
+ if ((items[i] != null) && (items[i].Length > 0)) {
+ string toCompile;
+
+ if (items[i][0] == '+') {
+ toCompile = items[i].Substring(1, items[i].Length - 1);
+ }
+ else if (items[i][0] == '-') {
+ toCompile = items[i].Substring(1, items[i].Length - 1);
+ }
+ else {
+ toCompile = items[i];
+ }
+
+ Regex testRegex = new Regex(toCompile, RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ }
+ }
+ }
+ catch (ArgumentException) {
+ result = false;
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Split a string into its component pieces
+ /// </summary>
+ /// <param name="original">The original string</param>
+ /// <returns>Returns a <see cref="T:System.String[]"/> containing the individual filter elements.</returns>
+ public static string[] SplitQuoted(string original)
+ {
+ char escape = '\\';
+ char[] separators = { ';' };
+
+ ArrayList result = new ArrayList();
+
+ if ((original != null) && (original.Length > 0)) {
+ int endIndex = -1;
+ StringBuilder b = new StringBuilder();
+
+ while (endIndex < original.Length) {
+ endIndex += 1;
+ if (endIndex >= original.Length) {
+ result.Add(b.ToString());
+ }
+ else if (original[endIndex] == escape) {
+ endIndex += 1;
+ if (endIndex >= original.Length) {
+#if NETCF_1_0
+ throw new ArgumentException("Missing terminating escape character");
+#else
+ throw new ArgumentException("Missing terminating escape character", "original");
+#endif
+ }
+
+ b.Append(original[endIndex]);
+ }
+ else {
+ if (Array.IndexOf(separators, original[endIndex]) >= 0) {
+ result.Add(b.ToString());
+ b.Length = 0;
+ }
+ else {
+ b.Append(original[endIndex]);
+ }
+ }
+ }
+ }
+
+ return (string[])result.ToArray(typeof(string));
+ }
+
+ /// <summary>
+ /// Convert this filter to its string equivalent.
+ /// </summary>
+ /// <returns>The string equivalent for this filter.</returns>
+ public override string ToString()
+ {
+ return filter_;
+ }
+
+ /// <summary>
+ /// Test a value to see if it is included by the filter.
+ /// </summary>
+ /// <param name="name">The value to test.</param>
+ /// <returns>True if the value is included, false otherwise.</returns>
+ public bool IsIncluded(string name)
+ {
+ bool result = false;
+ if ( inclusions_.Count == 0 ) {
+ result = true;
+ }
+ else {
+ foreach ( Regex r in inclusions_ ) {
+ if ( r.IsMatch(name) ) {
+ result = true;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// <summary>
+ /// Test a value to see if it is excluded by the filter.
+ /// </summary>
+ /// <param name="name">The value to test.</param>
+ /// <returns>True if the value is excluded, false otherwise.</returns>
+ public bool IsExcluded(string name)
+ {
+ bool result = false;
+ foreach ( Regex r in exclusions_ ) {
+ if ( r.IsMatch(name) ) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+ #region IScanFilter Members
+ /// <summary>
+ /// Test a value to see if it matches the filter.
+ /// </summary>
+ /// <param name="name">The value to test.</param>
+ /// <returns>True if the value matches, false otherwise.</returns>
+ public bool IsMatch(string name)
+ {
+ return (IsIncluded(name) == true) && (IsExcluded(name) == false);
+ }
+ #endregion
+
+ /// <summary>
+ /// Compile this filter.
+ /// </summary>
+ void Compile()
+ {
+ // TODO: Check to see if combining RE's makes it faster/smaller.
+ // simple scheme would be to have one RE for inclusion and one for exclusion.
+ if ( filter_ == null ) {
+ return;
+ }
+
+ string[] items = SplitQuoted(filter_);
+ for ( int i = 0; i < items.Length; ++i ) {
+ if ( (items[i] != null) && (items[i].Length > 0) ) {
+ bool include = (items[i][0] != '-');
+ string toCompile;
+
+ if ( items[i][0] == '+' ) {
+ toCompile = items[i].Substring(1, items[i].Length - 1);
+ }
+ else if ( items[i][0] == '-' ) {
+ toCompile = items[i].Substring(1, items[i].Length - 1);
+ }
+ else {
+ toCompile = items[i];
+ }
+
+ // NOTE: Regular expressions can fail to compile here for a number of reasons that cause an exception
+ // these are left unhandled here as the caller is responsible for ensuring all is valid.
+ // several functions IsValidFilterExpression and IsValidExpression are provided for such checking
+ if ( include ) {
+ inclusions_.Add(new Regex(toCompile, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline));
+ }
+ else {
+ exclusions_.Add(new Regex(toCompile, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline));
+ }
+ }
+ }
+ }
+
+ #region Instance Fields
+ string filter_;
+ ArrayList inclusions_;
+ ArrayList exclusions_;
+ #endregion
+ }
+}
View
334 MtnFrameGrabProvider/SharpZipLib/Core/PathFilter.cs
@@ -0,0 +1,334 @@
+// PathFilter.cs
+//
+// Copyright 2005 John Reilly
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give you
+// permission to link this library with independent modules to produce an
+// executable, regardless of the license terms of these independent
+// modules, and to copy and distribute the resulting executable under
+// terms of your choice, provided that you also meet, for each linked
+// independent module, the terms and conditions of the license of that
+// module. An independent module is a module which is not derived from
+// or based on this library. If you modify this library, you may extend
+// this exception to your version of the library, but you are not
+// obligated to do so. If you do not wish to do so, delete this
+// exception statement from your version.
+
+using System;
+using System.IO;
+
+namespace ICSharpCode.SharpZipLib.Core
+{
+ /// <summary>
+ /// PathFilter filters directories and files using a form of <see cref="System.Text.RegularExpressions.Regex">regular expressions</see>
+ /// by full path name.
+ /// See <see cref="NameFilter">NameFilter</see> for more detail on filtering.
+ /// </summary>
+ public class PathFilter : IScanFilter
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialise a new instance of <see cref="PathFilter"></see>.
+ /// </summary>
+ /// <param name="filter">The <see cref="NameFilter">filter</see> expression to apply.</param>
+ public PathFilter(string filter)
+ {
+ nameFilter_ = new NameFilter(filter);
+ }
+ #endregion
+
+ #region IScanFilter Members
+ /// <summary>
+ /// Test a name to see if it matches the filter.
+ /// </summary>
+ /// <param name="name">The name to test.</param>
+ /// <returns>True if the name matches, false otherwise.</returns>
+ /// <remarks><see cref="Path.GetFullPath(string)"/> is used to get the full path before matching.</remarks>
+ public virtual bool IsMatch(string name)
+ {
+ bool result = false;
+
+ if ( name != null ) {
+ string cooked = (name.Length > 0) ? Path.GetFullPath(name) : "";
+ result = nameFilter_.IsMatch(cooked);
+ }
+ return result;
+ }
+ #endregion
+
+ #region Instance Fields
+ NameFilter nameFilter_;
+ #endregion
+ }
+
+ /// <summary>
+ /// ExtendedPathFilter filters based on name, file size, and the last write time of the file.
+ /// </summary>
+ /// <remarks>Provides an example of how to customise filtering.</remarks>
+ public class ExtendedPathFilter : PathFilter
+ {
+ #region Constructors
+ /// <summary>
+ /// Initialise a new instance of ExtendedPathFilter.
+ /// </summary>
+ /// <param name="filter">The filter to apply.</param>
+ /// <param name="minSize">The minimum file size to include.</param>
+ /// <param name="maxSize">The maximum file size to include.</param>
+ public ExtendedPathFilter(string filter,
+ long minSize, long maxSize)
+ : base(filter)