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

搜索引擎

开发平台:

ASP/ASPX

  1. using System;
  2. using System.Text;
  3. using System.Runtime.InteropServices;
  4. //Contains IFilter interface translation
  5. //Most translations are from PInvoke.net
  6. //http://pinvoke.net/default.aspx/Interfaces.IFilter
  7. namespace EPocalipse.IFilter
  8. {
  9.   [StructLayout(LayoutKind.Sequential)]
  10.   public struct FULLPROPSPEC 
  11.   { 
  12.     public Guid guidPropSet;
  13.     public PROPSPEC psProperty;
  14.   }
  15.   [StructLayout(LayoutKind.Sequential)]
  16.   internal struct FILTERREGION 
  17.   {
  18.     public int idChunk;
  19.     public int cwcStart;
  20.     public int cwcExtent;
  21.   }
  22.   [StructLayout(LayoutKind.Explicit)]
  23.   public struct PROPSPEC
  24.   {
  25.     [FieldOffset(0)] public int ulKind;     // 0 - string used; 1 - PROPID
  26.     [FieldOffset(4)] public int propid;    
  27.     [FieldOffset(4)] public IntPtr lpwstr;
  28.   }
  29.   [Flags]
  30.   internal enum IFILTER_FLAGS 
  31.   {
  32.     /// <summary>
  33.     /// The caller should use the IPropertySetStorage and IPropertyStorage
  34.     /// interfaces to locate additional properties. 
  35.     /// When this flag is set, properties available through COM
  36.     /// enumerators should not be returned from IFilter. 
  37.     /// </summary>
  38.     IFILTER_FLAGS_OLE_PROPERTIES = 1
  39.   }
  40.   /// <summary>
  41.   /// Flags controlling the operation of the FileFilter
  42.   /// instance.
  43.   /// </summary>
  44.   [Flags]
  45.   internal enum IFILTER_INIT
  46.   {
  47.     NONE = 0,
  48.     /// <summary>
  49.     /// Paragraph breaks should be marked with the Unicode PARAGRAPH
  50.     /// SEPARATOR (0x2029)
  51.     /// </summary>
  52.     CANON_PARAGRAPHS = 1,
  53.     /// <summary>
  54.     /// Soft returns, such as the newline character in Microsoft Word, should
  55.     /// be replaced by hard returnsLINE SEPARATOR (0x2028). Existing hard
  56.     /// returns can be doubled. A carriage return (0x000D), line feed (0x000A),
  57.     /// or the carriage return and line feed in combination should be considered
  58.     /// a hard return. The intent is to enable pattern-expression matches that
  59.     /// match against observed line breaks. 
  60.     /// </summary>
  61.     HARD_LINE_BREAKS = 2,
  62.     /// <summary>
  63.     /// Various word-processing programs have forms of hyphens that are not
  64.     /// represented in the host character set, such as optional hyphens
  65.     /// (appearing only at the end of a line) and nonbreaking hyphens. This flag
  66.     /// indicates that optional hyphens are to be converted to nulls, and
  67.     /// non-breaking hyphens are to be converted to normal hyphens (0x2010), or
  68.     /// HYPHEN-MINUSES (0x002D). 
  69.     /// </summary>
  70.     CANON_HYPHENS = 4,
  71.     /// <summary>
  72.     /// Just as the CANON_HYPHENS flag standardizes hyphens,
  73.     /// this one standardizes spaces. All special space characters, such as
  74.     /// nonbreaking spaces, are converted to the standard space character
  75.     /// (0x0020). 
  76.     /// </summary>
  77.     CANON_SPACES = 8,
  78.     /// <summary>
  79.     /// Indicates that the client wants text split into chunks representing
  80.     /// public value-type properties. 
  81.     /// </summary>
  82.     APPLY_INDEX_ATTRIBUTES = 16,
  83.     /// <summary>
  84.     /// Indicates that the client wants text split into chunks representing
  85.     /// properties determined during the indexing process. 
  86.     /// </summary>
  87.     APPLY_CRAWL_ATTRIBUTES = 256,
  88.     /// <summary>
  89.     /// Any properties not covered by the APPLY_INDEX_ATTRIBUTES
  90.     /// and APPLY_CRAWL_ATTRIBUTES flags should be emitted. 
  91.     /// </summary>
  92.     APPLY_OTHER_ATTRIBUTES = 32,
  93.     /// <summary>
  94.     /// Optimizes IFilter for indexing because the client calls the
  95.     /// IFilter::Init method only once and does not call IFilter::BindRegion.
  96.     /// This eliminates the possibility of accessing a chunk both before and
  97.     /// after accessing another chunk. 
  98.     /// </summary>
  99.     INDEXING_ONLY = 64,
  100.     /// <summary>
  101.     /// The text extraction process must recursively search all linked
  102.     /// objects within the document. If a link is unavailable, the
  103.     /// IFilter::GetChunk call that would have obtained the first chunk of the
  104.     /// link should return FILTER_E_LINK_UNAVAILABLE. 
  105.     /// </summary>
  106.     SEARCH_LINKS = 128,
  107.     /// <summary>
  108.     /// The content indexing process can return property values set by the  filter. 
  109.     /// </summary>
  110.     FILTER_OWNED_VALUE_OK = 512
  111.   }
  112.   public struct STAT_CHUNK 
  113.   {
  114.     /// <summary>
  115.     /// The chunk identifier. Chunk identifiers must be unique for the
  116.     /// current instance of the IFilter interface. 
  117.     /// Chunk identifiers must be in ascending order. The order in which
  118.     /// chunks are numbered should correspond to the order in which they appear
  119.     /// in the source document. Some search engines can take advantage of the
  120.     /// proximity of chunks of various properties. If so, the order in which
  121.     /// chunks with different properties are emitted will be important to the
  122.     /// search engine. 
  123.     /// </summary>
  124.     public int idChunk;
  125.     /// <summary>
  126.     /// The type of break that separates the previous chunk from the current
  127.     ///  chunk. Values are from the CHUNK_BREAKTYPE enumeration. 
  128.     /// </summary>
  129.     [MarshalAs(UnmanagedType.U4)]
  130.     public CHUNK_BREAKTYPE breakType;
  131.     /// <summary>
  132.     /// Flags indicate whether this chunk contains a text-type or a
  133.     /// value-type property. 
  134.     /// Flag values are taken from the CHUNKSTATE enumeration. If the CHUNK_TEXT flag is set, 
  135.     /// IFilter::GetText should be used to retrieve the contents of the chunk
  136.     /// as a series of words. 
  137.     /// If the CHUNK_VALUE flag is set, IFilter::GetValue should be used to retrieve 
  138.     /// the value and treat it as a single property value. If the filter dictates that the same 
  139.     /// content be treated as both text and as a value, the chunk should be emitted twice in two       
  140.     /// different chunks, each with one flag set. 
  141.     /// </summary>
  142.     [MarshalAs(UnmanagedType.U4)]
  143.     public CHUNKSTATE flags;
  144.     /// <summary>
  145.     /// The language and sublanguage associated with a chunk of text. Chunk locale is used 
  146.     /// by document indexers to perform proper word breaking of text. If the chunk is 
  147.     /// neither text-type nor a value-type with data type VT_LPWSTR, VT_LPSTR or VT_BSTR, 
  148.     /// this field is ignored. 
  149.     /// </summary>
  150.     public int locale;
  151.     /// <summary>
  152.     /// The property to be applied to the chunk. If a filter requires that       the same text 
  153.     /// have more than one property, it needs to emit the text once for each       property 
  154.     /// in separate chunks. 
  155.     /// </summary>
  156.     public FULLPROPSPEC attribute;
  157.     /// <summary>
  158.     /// The ID of the source of a chunk. The value of the idChunkSource     
  159.     /// member depends on the nature of the chunk: 
  160.     /// If the chunk is a text-type property, the value of the idChunkSource       
  161.     /// member must be the same as the value of the idChunk member. 
  162.     /// If the chunk is an public value-type property derived from textual       
  163.     /// content, the value of the idChunkSource member is the chunk ID for the
  164.     /// text-type chunk from which it is derived. 
  165.     /// If the filter attributes specify to return only public value-type
  166.     /// properties, there is no content chunk from which to derive the current
  167.     /// public value-type property. In this case, the value of the
  168.     /// idChunkSource member must be set to zero, which is an invalid chunk. 
  169.     /// </summary>
  170.     public int idChunkSource;
  171.     /// <summary>
  172.     /// The offset from which the source text for a derived chunk starts in
  173.     /// the source chunk. 
  174.     /// </summary>
  175.     public int cwcStartSource;
  176.     /// <summary>
  177.     /// The length in characters of the source text from which the current
  178.     /// chunk was derived. 
  179.     /// A zero value signifies character-by-character correspondence between
  180.     /// the source text and 
  181.     /// the derived text. A nonzero value means that no such direct
  182.     /// correspondence exists
  183.     /// </summary>
  184.     public int cwcLenSource;
  185.   }
  186.   /// <summary>
  187.   /// Enumerates the different breaking types that occur between 
  188.   /// chunks of text read out by the FileFilter.
  189.   /// </summary>
  190.   public enum CHUNK_BREAKTYPE
  191.   {
  192.     /// <summary>
  193.     /// No break is placed between the current chunk and the previous chunk.
  194.     /// The chunks are glued together. 
  195.     /// </summary>
  196.     CHUNK_NO_BREAK = 0,
  197.     /// <summary>
  198.     /// A word break is placed between this chunk and the previous chunk that
  199.     /// had the same attribute. 
  200.     /// Use of CHUNK_EOW should be minimized because the choice of word
  201.     /// breaks is language-dependent, 
  202.     /// so determining word breaks is best left to the search engine. 
  203.     /// </summary>
  204.     CHUNK_EOW = 1,
  205.     /// <summary>
  206.     /// A sentence break is placed between this chunk and the previous chunk
  207.     /// that had the same attribute. 
  208.     /// </summary>
  209.     CHUNK_EOS = 2,
  210.     /// <summary>
  211.     /// A paragraph break is placed between this chunk and the previous chunk
  212.     /// that had the same attribute.
  213.     /// </summary>     
  214.     CHUNK_EOP = 3,
  215.     /// <summary>
  216.     /// A chapter break is placed between this chunk and the previous chunk
  217.     /// that had the same attribute. 
  218.     /// </summary>
  219.     CHUNK_EOC = 4
  220.   }
  221.   public enum CHUNKSTATE 
  222.   {
  223.     /// <summary>
  224.     /// The current chunk is a text-type property.
  225.     /// </summary>
  226.     CHUNK_TEXT = 0x1,
  227.     /// <summary>
  228.     /// The current chunk is a value-type property. 
  229.     /// </summary>
  230.     CHUNK_VALUE = 0x2,
  231.     /// <summary>
  232.     /// Reserved
  233.     /// </summary>
  234.     CHUNK_FILTER_OWNED_VALUE = 0x4
  235.   }
  236.   internal enum IFilterReturnCode : uint 
  237.   {
  238.     /// <summary>
  239.     /// Success
  240.     /// </summary>
  241.     S_OK = 0,
  242.     /// <summary>
  243.     /// The function was denied access to the filter file. 
  244.     /// </summary>
  245.     E_ACCESSDENIED = 0x80070005,
  246.     /// <summary>
  247.     /// The function encountered an invalid handle,
  248.     /// probably due to a low-memory situation. 
  249.     /// </summary>
  250.     E_HANDLE = 0x80070006,
  251.     /// <summary>
  252.     /// The function received an invalid parameter.
  253.     /// </summary>
  254.     E_INVALIDARG = 0x80070057,
  255.     /// <summary>
  256.     /// Out of memory
  257.     /// </summary>
  258.     E_OUTOFMEMORY = 0x8007000E,
  259.     /// <summary>
  260.     /// Not implemented
  261.     /// </summary>
  262.     E_NOTIMPL = 0x80004001,
  263.     /// <summary>
  264.     /// Unknown error
  265.     /// </summary>
  266.     E_FAIL = 0x80000008,
  267.     /// <summary>
  268.     /// File not filtered due to password protection
  269.     /// </summary>
  270.     FILTER_E_PASSWORD = 0x8004170B,
  271.     /// <summary>
  272.     /// The document format is not recognised by the filter
  273.     /// </summary>
  274.     FILTER_E_UNKNOWNFORMAT = 0x8004170C,
  275.     /// <summary>
  276.     /// No text in current chunk
  277.     /// </summary>
  278.     FILTER_E_NO_TEXT = 0x80041705,
  279.     /// <summary>
  280.     /// No more chunks of text available in object
  281.     /// </summary>
  282.     FILTER_E_END_OF_CHUNKS = 0x80041700,
  283.     /// <summary>
  284.     /// No more text available in chunk
  285.     /// </summary>
  286.     FILTER_E_NO_MORE_TEXT = 0x80041701,
  287.     /// <summary>
  288.     /// No more property values available in chunk
  289.     /// </summary>
  290.     FILTER_E_NO_MORE_VALUES = 0x80041702,
  291.     /// <summary>
  292.     /// Unable to access object
  293.     /// </summary>
  294.     FILTER_E_ACCESS = 0x80041703,
  295.     /// <summary>
  296.     /// Moniker doesn't cover entire region
  297.     /// </summary>
  298.     FILTER_W_MONIKER_CLIPPED = 0x00041704,
  299.     /// <summary>
  300.     /// Unable to bind IFilter for embedded object
  301.     /// </summary>
  302.     FILTER_E_EMBEDDING_UNAVAILABLE = 0x80041707,
  303.     /// <summary>
  304.     /// Unable to bind IFilter for linked object
  305.     /// </summary>
  306.     FILTER_E_LINK_UNAVAILABLE = 0x80041708,
  307.     /// <summary>
  308.     ///  This is the last text in the current chunk
  309.     /// </summary>
  310.     FILTER_S_LAST_TEXT = 0x00041709,
  311.     /// <summary>
  312.     /// This is the last value in the current chunk
  313.     /// </summary>
  314.     FILTER_S_LAST_VALUES = 0x0004170A
  315.   }
  316.   [ComImport, Guid("89BCB740-6119-101A-BCB7-00DD010655AF")]
  317.   [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  318.   internal interface IFilter
  319.   {
  320.     /// <summary>
  321.     /// The IFilter::Init method initializes a filtering session.
  322.     /// </summary>
  323.     [PreserveSig]
  324.     IFilterReturnCode Init(
  325.       //[in] Flag settings from the IFILTER_INIT enumeration for
  326.       // controlling text standardization, property output, embedding
  327.       // scope, and IFilter access patterns. 
  328.       IFILTER_INIT grfFlags,
  329.       // [in] The size of the attributes array. When nonzero, cAttributes
  330.       //  takes 
  331.       // precedence over attributes specified in grfFlags. If no
  332.       // attribute flags 
  333.       // are specified and cAttributes is zero, the default is given by
  334.       // the 
  335.       // PSGUID_STORAGE storage property set, which contains the date and
  336.       //  time 
  337.       // of the last write to the file, size, and so on; and by the
  338.       //  PID_STG_CONTENTS 
  339.       // 'contents' property, which maps to the main contents of the
  340.       // file. 
  341.       // For more information about properties and property sets, see
  342.       // Property Sets. 
  343.       int cAttributes,
  344.       //[in] Array of pointers to FULLPROPSPEC structures for the
  345.       // requested properties. 
  346.       // When cAttributes is nonzero, only the properties in aAttributes
  347.       // are returned. 
  348.       IntPtr aAttributes,
  349.       // [out] Information about additional properties available to the
  350.       //  caller; from the IFILTER_FLAGS enumeration. 
  351.       out IFILTER_FLAGS pdwFlags);
  352.     /// <summary>
  353.     /// The IFilter::GetChunk method positions the filter at the beginning
  354.     /// of the next chunk, 
  355.     /// or at the first chunk if this is the first call to the GetChunk
  356.     /// method, and returns a description of the current chunk. 
  357.     /// </summary>
  358.     [PreserveSig]
  359.     IFilterReturnCode GetChunk(out STAT_CHUNK pStat);
  360.     /// <summary>
  361.     /// The IFilter::GetText method retrieves text (text-type properties)
  362.     /// from the current chunk, 
  363.     /// which must have a CHUNKSTATE enumeration value of CHUNK_TEXT.
  364.     /// </summary>
  365.     [PreserveSig]
  366.     IFilterReturnCode GetText(
  367.       // [in/out] On entry, the size of awcBuffer array in wide/Unicode
  368.       // characters. On exit, the number of Unicode characters written to
  369.       // awcBuffer. 
  370.       // Note that this value is not the number of bytes in the buffer. 
  371.       ref uint pcwcBuffer,
  372.       // Text retrieved from the current chunk. Do not terminate the
  373.       // buffer with a character.  
  374.       [Out(), MarshalAs(UnmanagedType.LPArray)] 
  375.       char[] awcBuffer);
  376.     /// <summary>
  377.     /// The IFilter::GetValue method retrieves a value (public
  378.     /// value-type property) from a chunk, 
  379.     /// which must have a CHUNKSTATE enumeration value of CHUNK_VALUE.
  380.     /// </summary>
  381.     /// <remarks>
  382.     /// IFilter::GetValue
  383.     /// http://msdn2.microsoft.com/en-us/library/ms690927.aspx
  384.     /// Filtering File Properties
  385.     /// http://msdn2.microsoft.com/en-us/library/ms692552.aspx
  386.     /// </remarks>
  387.     [PreserveSig]
  388.     int GetValue(
  389.       // Allocate the PROPVARIANT structure with CoTaskMemAlloc. Some
  390.       // PROPVARIANT 
  391.       // structures contain pointers, which can be freed by calling the
  392.       // PropVariantClear function. 
  393.       // It is up to the caller of the GetValue method to call the
  394.       //   PropVariantClear method.            
  395.       // ref IntPtr ppPropValue
  396.       // [MarshalAs(UnmanagedType.Struct)]
  397.       ref IntPtr PropVal);
  398.     /// <summary>
  399.     /// The IFilter::BindRegion method retrieves an interface representing
  400.     /// the specified portion of the object. 
  401.     /// Currently reserved for future use.
  402.     /// </summary>
  403.     [PreserveSig]
  404.     int BindRegion(ref FILTERREGION origPos,
  405.       ref Guid riid, ref object ppunk);
  406.   }
  407. }