private static string LoadAndInitIFilterAndReadAll(Stream stream, string extension) { // Get an IFilter for a file or file extension IFilter filter = null; IFilterReturnCode result = NativeMethods.LoadIFilter(extension, null, ref filter); if (result != IFilterReturnCode.S_OK) { Marshal.ThrowExceptionForHR((int)result); } // Copy the content to global memory byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); IntPtr nativePtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, nativePtr, buffer.Length); // Create a COM stream IStream comStream; NativeMethods.CreateStreamOnHGlobal(nativePtr, true, out comStream); // Load the contents to the iFilter using IPersistStream interface var persistStream = (IPersistStream)filter; persistStream.Load(comStream); // Initialize iFilter IFILTER_INIT iflags = IFILTER_INIT.CANON_HYPHENS | IFILTER_INIT.CANON_PARAGRAPHS | IFILTER_INIT.CANON_SPACES | IFILTER_INIT.APPLY_INDEX_ATTRIBUTES | IFILTER_INIT.HARD_LINE_BREAKS | IFILTER_INIT.FILTER_OWNED_VALUE_OK; IFILTER_FLAGS filterFlags; result = filter.Init(iflags, 0, IntPtr.Zero, out filterFlags); var text = ExtractTextFromIFilter(filter); if (filter != null) { Marshal.ReleaseComObject(filter); } return(text); }
public override int Read(char[] array, int offset, int count) { int endOfChunksCount = 0; int charsRead = 0; while (!_done && charsRead < count) { if (_charsLeftFromLastRead != null) { int charsToCopy = (_charsLeftFromLastRead.Length < count - charsRead)?_charsLeftFromLastRead.Length:count - charsRead; Array.Copy(_charsLeftFromLastRead, 0, array, offset + charsRead, charsToCopy); charsRead += charsToCopy; if (charsToCopy < _charsLeftFromLastRead.Length) { char[] tmp = new char[_charsLeftFromLastRead.Length - charsToCopy]; Array.Copy(_charsLeftFromLastRead, charsToCopy, tmp, 0, tmp.Length); _charsLeftFromLastRead = tmp; } else { _charsLeftFromLastRead = null; } continue; } ; if (!_currentChunkValid) { IFilterReturnCode res = _filter.GetChunk(out _currentChunk); _currentChunkValid = (res == IFilterReturnCode.S_OK) && ((_currentChunk.flags & CHUNKSTATE.CHUNK_TEXT) != 0); if (res == IFilterReturnCode.FILTER_E_END_OF_CHUNKS) { endOfChunksCount++; } if (endOfChunksCount > 1) { _done = true; //That's it. no more chuncks available } } if (_currentChunkValid) { uint bufLength = (uint)(count - charsRead); if (bufLength < 8192) { bufLength = 8192; //Read ahead } char[] buffer = new char[bufLength]; IFilterReturnCode res = _filter.GetText(ref bufLength, buffer); if (res == IFilterReturnCode.S_OK || res == IFilterReturnCode.FILTER_S_LAST_TEXT) { int cRead = (int)bufLength; if (cRead + charsRead > count) { int charsLeft = (cRead + charsRead - count); _charsLeftFromLastRead = new char[charsLeft]; Array.Copy(buffer, cRead - charsLeft, _charsLeftFromLastRead, 0, charsLeft); cRead -= charsLeft; } else { _charsLeftFromLastRead = null; } Array.Copy(buffer, 0, array, offset + charsRead, cRead); charsRead += cRead; } if (res == IFilterReturnCode.FILTER_S_LAST_TEXT || res == IFilterReturnCode.FILTER_E_NO_MORE_TEXT) { _currentChunkValid = false; } } } return(charsRead); }