FilterReader.cs
上传用户:huiyue
上传日期:2022-04-08
资源大小:1429k
文件大小:3k
源码类别:

搜索引擎

开发平台:

ASP/ASPX

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.IO;
  5. using System.Runtime.InteropServices;
  6. namespace EPocalipse.IFilter
  7. {
  8.   /// <summary>
  9.   /// Implements a TextReader that reads from an IFilter. 
  10.   /// </summary>
  11.   public class FilterReader : TextReader
  12.   {
  13.     IFilter _filter;
  14.     private bool _done;
  15.     private STAT_CHUNK _currentChunk;
  16.     private bool _currentChunkValid;
  17.     private char[] _charsLeftFromLastRead;
  18.     public override void Close()
  19.     {
  20.       Dispose(true);
  21.       GC.SuppressFinalize(this);
  22.     }
  23.     ~FilterReader()
  24.     {
  25.       Dispose(false);
  26.     }
  27.     protected override void Dispose(bool disposing)
  28.     {
  29.       if (_filter!=null)
  30.         Marshal.ReleaseComObject(_filter);
  31.     }
  32.     public override int Read(char[] array, int offset, int count)
  33.     {
  34.       int endOfChunksCount=0;
  35.       int charsRead=0;
  36.       while (!_done && charsRead<count)
  37.       {
  38.         if (_charsLeftFromLastRead!=null)
  39.         {
  40.           int charsToCopy=(_charsLeftFromLastRead.Length<count-charsRead)?_charsLeftFromLastRead.Length:count-charsRead;
  41.           Array.Copy(_charsLeftFromLastRead,0, array, offset+charsRead, charsToCopy);
  42.           charsRead+=charsToCopy;
  43.           if (charsToCopy<_charsLeftFromLastRead.Length)
  44.           {
  45.             char[] tmp=new char[_charsLeftFromLastRead.Length-charsToCopy];
  46.             Array.Copy(_charsLeftFromLastRead, charsToCopy, tmp, 0, tmp.Length);
  47.             _charsLeftFromLastRead=tmp;
  48.           }
  49.           else
  50.             _charsLeftFromLastRead=null;
  51.           continue;
  52.         };
  53.         if (!_currentChunkValid)
  54.         {
  55.           IFilterReturnCode res=_filter.GetChunk(out _currentChunk);
  56.           _currentChunkValid=(res==IFilterReturnCode.S_OK) && ((_currentChunk.flags & CHUNKSTATE.CHUNK_TEXT)!=0);
  57.           if (res==IFilterReturnCode.FILTER_E_END_OF_CHUNKS)
  58.             endOfChunksCount++;
  59.           if (endOfChunksCount>1)
  60.             _done=true; //That's it. no more chuncks available
  61.         }
  62.         if (_currentChunkValid)
  63.         {
  64.           uint bufLength=(uint)(count-charsRead);
  65.           if (bufLength<8192)
  66.             bufLength=8192; //Read ahead
  67.           char[] buffer=new char[bufLength];
  68.           IFilterReturnCode res=_filter.GetText(ref bufLength, buffer);
  69.           if (res==IFilterReturnCode.S_OK || res==IFilterReturnCode.FILTER_S_LAST_TEXT)
  70.           {
  71.             int cRead=(int)bufLength;
  72.             if (cRead+charsRead>count)
  73.             {
  74.               int charsLeft=(cRead+charsRead-count);
  75.               _charsLeftFromLastRead=new char[charsLeft];
  76.               Array.Copy(buffer, cRead-charsLeft, _charsLeftFromLastRead, 0, charsLeft);
  77.               cRead-=charsLeft;
  78.             }
  79.             else
  80.               _charsLeftFromLastRead=null;
  81.             Array.Copy(buffer, 0, array, offset+charsRead, cRead);
  82.             charsRead+=cRead;
  83.           }
  84.           if (res==IFilterReturnCode.FILTER_S_LAST_TEXT || res==IFilterReturnCode.FILTER_E_NO_MORE_TEXT)
  85.             _currentChunkValid=false;
  86.         }
  87.       }
  88.       return charsRead;
  89.     }
  90.     public FilterReader(string fileName)
  91.     {
  92.       _filter=FilterLoader.LoadAndInitIFilter(fileName);
  93.       if (_filter==null)
  94.         throw new ArgumentException("no filter defined for "+fileName);
  95.     }
  96.   }
  97. }