// @pymethod |PyIFilter|GetValue|Description of GetValue.
PyObject *PyIFilter::GetValue(PyObject *self, PyObject *args)
{
	IFilter *pIF = GetI(self);
	if ( pIF == NULL )
		return NULL;

	if ( !PyArg_ParseTuple(args, ":GetValue") )
		return NULL;
	
	HRESULT hr;
	PROPVARIANT * pPropValue = 0;
	PY_INTERFACE_PRECALL;
	hr = pIF->GetValue(&pPropValue );
	PY_INTERFACE_POSTCALL;

	if ( FAILED(hr) ){
		return PyCom_BuildPyException(hr, pIF, IID_IFilter );
	}


	if (pPropValue){
		PyObject *obRet = PyObject_FromPROPVARIANT(pPropValue);
		PropVariantClear(pPropValue);
		CoTaskMemFree(pPropValue);
		return obRet;
	}
	
	Py_INCREF(Py_None);
	return Py_None;
}
// @pymethod |PyIFilter|GetText|Description of GetText.
PyObject *PyIFilter::GetText(PyObject *self, PyObject *args)
{
	IFilter *pIF = GetI(self);
	if ( pIF == NULL )
		return NULL;

	// @pyparm <int>|nBufSize|size of text buffer to create
	ULONG nBufSize = 0; 
	if ( !PyArg_ParseTuple(args, "|i:GetText", &nBufSize) )
		return NULL;

	HRESULT hr;
	if (nBufSize == 0)
		nBufSize = 8192; // 8k default

	WCHAR *wBuffer = (WCHAR *)PyMem_Malloc((nBufSize+1)*sizeof(WCHAR));
	if (!wBuffer){
		PyErr_SetString(PyExc_MemoryError, "getting text");
		return NULL;
	}

	PY_INTERFACE_PRECALL;
	hr = pIF->GetText( &nBufSize, wBuffer );
	PY_INTERFACE_POSTCALL;

	if ( FAILED(hr) ) {
		PyMem_Free(wBuffer);
		return PyCom_BuildPyException(hr, pIF, IID_IFilter );
	}

	PyObject *obRet =  PyWinObject_FromWCHAR(wBuffer, nBufSize);
	PyMem_Free(wBuffer);
	return obRet;
}
  // Launch filter test.
  Tbool testFilter(IFilter& a_crFilter, IReaderWriter& a_crStream)
  { CALL
    CString buffer(STR("The quick brown fox jumps over the lazy dog"));

    // Open filter for writing.
    UT_ASSERT(a_crFilter.open(IStream::e_OPEN_WRITE));
    UT_ASSERT(a_crFilter.isOpened());
    UT_ASSERT(a_crStream.isOpened());

    // Write into the filter.
    UT_ASSERT(a_crFilter.write(buffer).getFirst());

    // Close filter.
    UT_ASSERT(a_crFilter.close());
    UT_ASSERT(!a_crFilter.isOpened());
    UT_ASSERT(!a_crStream.isOpened());

    // Open filter for reading.
    UT_ASSERT(a_crFilter.open(IStream::e_OPEN_READ));
    UT_ASSERT(a_crFilter.isOpened());
    UT_ASSERT(a_crStream.isOpened());

    // Read from the filter.
    CString read_buffer;
    UT_ASSERT(a_crFilter.read(read_buffer).getFirst());

    // Close filter.
    UT_ASSERT(a_crFilter.close());
    UT_ASSERT(!a_crFilter.isOpened());
    UT_ASSERT(!a_crStream.isOpened());

    // Compare strings.
    return (read_buffer == buffer);
  }
Exemple #4
0
	IFilter* cAudioEffects::createFilter()
	{
		cAudioMutexBasicLock lock(Mutex);
		IFilter* filter = CAUDIO_NEW cFilter(&EFXInterface);

		if(filter && filter->isValid())
			return filter;

		return NULL;
	}
Exemple #5
0
void TestSuite::run_suite(
    const IFilter&      filter,
    ITestListener&      test_listener,
    TestResult&         test_suite_result,
    TestResult&         cumulated_result) const
{
    TestResult local_cumulated_result(cumulated_result);
    local_cumulated_result.merge(test_suite_result);

    bool has_begun_suite = false;

    for (size_t i = 0; i < impl->m_factories.size(); ++i)
    {
        ITestCaseFactory& factory = *impl->m_factories[i];

        // Skip test cases that aren't let through by the filter.
        if (!filter.accepts(factory.get_name()))
            continue;

        if (!has_begun_suite)
        {
            // Tell the listener that a test suite is about to be executed.
            test_listener.begin_suite(*this);
            test_suite_result.signal_suite_execution();
            has_begun_suite = true;
        }

        // Tell the listener that a test case is about to be executed.
        test_listener.begin_case(*this, factory.get_name());

        // Instantiate and run the test case.
        TestResult test_case_result;
        run_case(factory, test_listener, test_case_result);

        // Accumulate the test results.
        test_suite_result.merge(test_case_result);
        local_cumulated_result.merge(test_case_result);

        // Tell the listener that the test case execution has ended.
        test_listener.end_case(
            *this,
            factory.get_name(),
            test_suite_result,
            test_case_result,
            local_cumulated_result);
    }

    if (has_begun_suite)
    {
        // Report a test suite failure if one or more test cases failed.
        if (test_suite_result.get_case_failure_count() > 0)
            test_suite_result.signal_suite_failure();

        // Tell the listener that the test suite execution has ended.
        test_listener.end_suite(
            *this,
            test_suite_result,
            cumulated_result);
    }
}
// @pymethod |PyIFilter|GetChunk|Description of GetChunk.
PyObject *PyIFilter::GetChunk(PyObject *self, PyObject *args)
{
	IFilter *pIF = GetI(self);
	if ( pIF == NULL )
		return NULL;
	if ( !PyArg_ParseTuple(args, ":GetChunk") )
		return NULL;

	HRESULT hr;
	STAT_CHUNK stat;
	PY_INTERFACE_PRECALL;
	hr = pIF->GetChunk( &stat );
	PY_INTERFACE_POSTCALL;

	if ( FAILED(hr) )
		return PyCom_BuildPyException(hr, pIF, IID_IFilter );

	PyObject * obProp;
	if (stat.attribute.psProperty.ulKind == PRSPEC_LPWSTR){
		obProp = PyWinObject_FromWCHAR(stat.attribute.psProperty.lpwstr);
	}
	else {
		obProp = Py_BuildValue("i", stat.attribute.psProperty.propid);
	}

	PyObject * obAttr = Py_BuildValue("NN", 
									  PyWinObject_FromIID(stat.attribute.guidPropSet),
									  obProp);

	return Py_BuildValue("iiiiNiii",  stat.idChunk,
									  stat.breakType,
									  stat.flags,
									  stat.locale,
									  obAttr,
									  stat.idChunkSource,
									  stat.cwcStartSource,
									  stat.cwcLenSource);
}
// Run those test suites whose name pass a given filter.
void TestSuiteRepository::run(
    const IFilter&  filter,
    ITestListener&  test_listener,
    TestResult&     cumulated_result) const
{
    for (size_t i = 0; i < impl->m_suites.size(); ++i)
    {
        TestSuite& test_suite = *impl->m_suites[i];

        if (filter.accepts(test_suite.get_name()))
            test_suite.run(test_listener, cumulated_result);
        else test_suite.run(filter, test_listener, cumulated_result);
    }
}
//
// TODO: I don't support passing in a FULLPROPSEC array yet
//
PyObject *PyIFilter::Init(PyObject *self, PyObject *args)
{
	IFilter *pIF = GetI(self);
	if ( pIF == NULL )
		return NULL;

	const FULLPROPSPEC * aAttributes=NULL;
	ULONG cAttributes=0;
	
	ULONG grfFlags=0;
	ULONG flags = 0;
	if ( !PyArg_ParseTuple(args, "l:Init", &grfFlags) )
		return NULL;
	
	HRESULT hr;
	PY_INTERFACE_PRECALL;
	hr = pIF->Init( grfFlags, cAttributes, aAttributes, &flags );
	PY_INTERFACE_POSTCALL;

	if ( FAILED(hr) )
		return PyCom_BuildPyException(hr, pIF, IID_IFilter );

	return Py_BuildValue("l", flags);
}
void BenchmarkSuiteRepository::run(
    const IFilter&      filter,
    BenchmarkResult&    result) const
{
    for (size_t i = 0; i < impl->m_suites.size(); ++i)
    {
        BenchmarkSuite& suite = *impl->m_suites[i];

        // Create a benchmark result for this benchmark suite.
        BenchmarkResult suite_result;
        suite_result.add_listeners(result);

        // Run the benchmark suite.
        if (filter.accepts(suite.get_name()))
            suite.run(suite_result);
        else suite.run(filter, suite_result);

        // Merge the benchmark suite result into the final benchmark result.
        result.merge(suite_result);
    }
}
HRESULT Analyze(wchar_t* szPath) {
    HRESULT hr = S_OK;

    // Load the IFilter associated with the specified file
    IFilter* pFilter;
    hr = LoadIFilter(szPath, NULL, (void**)&pFilter);
    if (SUCCEEDED(hr)) {

        // Initialize the IFilter
        DWORD dwFlags = 0;
        hr = pFilter->Init(FILTER_INIT_OPTIONS,0,NULL,&dwFlags);
        if (SUCCEEDED(hr)) {
            wchar_t szBuffer[BUFLEN];
            ULONG ulSize;
            STAT_CHUNK ps;
            while (SUCCEEDED(hr))
            {

                // Retrieve the next chunk in the document
                hr = pFilter->GetChunk(&ps);
                if ( (FILTER_E_EMBEDDING_UNAVAILABLE == hr) || (FILTER_E_LINK_UNAVAILABLE == hr) ) {
                    hr = S_OK;
                    continue;
                } else if (FILTER_E_END_OF_CHUNKS == hr) {
                    hr = S_OK;
                    break;
                }
                while(SUCCEEDED(hr)) {

                    // Retrieve the next block of text in the current chunk 
                    ulSize = BUFLEN;
                    hr = pFilter->GetText(&ulSize, szBuffer);
                    if ( (FILTER_E_NO_TEXT == hr) || (FILTER_E_NO_MORE_TEXT  == hr) ) {
                        hr = S_OK;
                        break;
                    }
                    if (SUCCEEDED(hr) && (0 < ulSize)) {
                        szBuffer[ulSize] = '\0';

                        // Convert to UTF8
                        unsigned int cbMultiByte = WideCharToMultiByte(CP_UTF8, NULL, szBuffer, -1, NULL, 0, NULL, NULL);
                        if (0 == cbMultiByte) {
                            hr = E_FAIL;
							tcerr << "WideCharToMultiByte#1 invocation failed" << endl;
							errorMessagePrinted = true;
                        } else {
                            char* pchMultiByte = new char[cbMultiByte];
                            if (NULL == pchMultiByte) {
                                hr = E_OUTOFMEMORY;
                            } else {
                                if (0 == WideCharToMultiByte(CP_UTF8, NULL, szBuffer, -1, pchMultiByte, cbMultiByte, NULL, NULL)) {
                                    hr = E_FAIL;
									tcerr << "WideCharToMultiByte#2 invocation failed" << endl;
									errorMessagePrinted = true;
                                } else {

                                    // Write the UTF8 text to stdout
                                    if (cbMultiByte > fwrite(pchMultiByte, 1, cbMultiByte, stdout)) {
                                        hr = E_FAIL;
										tcerr << "Unable to write converted bytes to output" << endl;
										errorMessagePrinted = true;
                                    }
                                }
                                delete[] pchMultiByte;
                            }
                        }
                    }
                } 
            }
		} else {
			tcerr << "IFilter initialization failed with HRESULT " << hr << endl;
			errorMessagePrinted = true;
		}
        pFilter->Release(); 
	} else {
		tcerr << "IFilter loading failed with HRESULT " << hr << endl;
		errorMessagePrinted = true;
	}
    return hr;
}
Exemple #11
0
void BenchmarkSuite::run(
    const IFilter&      filter,
    BenchmarkResult&    suite_result) const
{
    BenchmarkingThreadContext benchmarking_context;
    bool has_begun_suite = false;

    for (size_t i = 0; i < impl->m_factories.size(); ++i)
    {
        IBenchmarkCaseFactory* factory = impl->m_factories[i];

        // Skip benchmark cases that aren't let through by the filter.
        if (!filter.accepts(factory->get_name()))
            continue;

        if (!has_begun_suite)
        {
            // Tell the listeners that a benchmark suite is about to be executed.
            suite_result.begin_suite(*this);
            suite_result.signal_suite_execution();
            has_begun_suite = true;
        }

        // Instantiate the benchmark case.
        auto_ptr<IBenchmarkCase> benchmark(factory->create());

        // Recreate the stopwatch (and the underlying timer) for every benchmark
        // case, since the CPU frequency will fluctuate quite a bit depending on
        // the CPU load.  We need an up-to-date frequency estimation in order to
        // compute accurate call rates.
        Impl::StopwatchType stopwatch(100000);

        // Tell the listeners that a benchmark case is about to be executed.
        suite_result.begin_case(*this, *benchmark.get());

#ifdef NDEBUG
        try
#endif
        {
            suite_result.signal_case_execution();

            // Estimate benchmarking parameters.
            Impl::BenchmarkParams params;
            Impl::estimate_benchmark_params(
                benchmark.get(),
                stopwatch,
                params);

            // Measure the overhead of calling IBenchmarkCase::run().
            const double overhead =
                Impl::measure_call_overhead(stopwatch, params);

            // Run the benchmark case.
            const double execution_time =
                Impl::measure_iteration_runtime(
                    benchmark.get(),
                    stopwatch,
                    params);

            // Gather the timing results.
            TimingResult timing_result;
            timing_result.m_iteration_count = params.m_iteration_count;
            timing_result.m_measurement_count = params.m_measurement_count;
            timing_result.m_frequency = static_cast<double>(stopwatch.get_timer().frequency());
            timing_result.m_ticks = execution_time > overhead ? execution_time - overhead : 0.0;

            // Post the timing result.
            suite_result.write(
                *this,
                *benchmark.get(),
                __FILE__,
                __LINE__,
                timing_result);
        }
#ifdef NDEBUG
        catch (const exception& e)
        {
            suite_result.write(
                *this,
                *benchmark.get(),
                __FILE__,
                __LINE__,
                "an unexpected exception was caught: %s.",
                e.what());

            suite_result.signal_case_failure();
        }
        catch (...)
        {
            suite_result.write(
                *this,
                *benchmark.get(),
                __FILE__,
                __LINE__,
                "an unexpected exception was caught (no details available).");

            suite_result.signal_case_failure();
        }
#endif

        // Tell the listeners that the benchmark case execution has ended.
        suite_result.end_case(*this, *benchmark.get());
    }

    if (has_begun_suite)
    {
        // Report a benchmark suite failure if one or more benchmark cases failed.
        if (suite_result.get_case_failure_count() > 0)
            suite_result.signal_suite_failure();

        // Tell the listeners that the benchmark suite execution has ended.
        suite_result.end_suite(*this);
    }
}
Exemple #12
0
void Video::play( char *fileName, DWORD )
{
	WCHAR wPath[100];
	HRESULT hr;
	IMediaControl *pMC;

	if(!init_success)
		return;

	MultiByteToWideChar( CP_ACP, 0, fileName, -1, wPath, 100 );

	if( (hr = pGraph->RenderFile(wPath, NULL)) == 0)
	{

		// use full screen video interface
		// try to change display mode
		IVideoWindow *iVideoWindow = NULL;
		if( (hr = pGraph->QueryInterface(IID_IVideoWindow, (void **) &iVideoWindow)) == 0)
		{
#ifdef CREATE_DUMMY_WINDOW
			if(hwnd)
			{
				HRESULT hr2 = iVideoWindow->put_MessageDrain((OAHWND) hwnd);
				hr2 = 0;
			}
#endif

#ifdef FULL_SCREEN_VIDEO
			IFilter *iFilter;
			if( pGraph->FindFilterByName(L"Video Renderer", &iFilter) == 0)
			{
				IBasicVideo *iBasicVideo;
				if( iFilter->QueryInterface(IID_IBasicVideo, (void **)&iBasicVideo) == 0)
				{
					IFullScreenVideo *iFullScreenVideo;
					IDirectDrawVideo *iDirectDrawVideo;
					if( iFilter->QueryInterface(IID_IFullScreenVideo, (void **)&iFullScreenVideo) == 0)
					{
						iFullScreenVideo->Release();
					}
					else if( iFilter->QueryInterface(IID_IDirectDrawVideo, (void **)&iDirectDrawVideo) == 0)
					{
						HRESULT hr2;
						hr2 = iDirectDrawVideo->UseWhenFullScreen(OATRUE);
						iDirectDrawVideo->Release();
					}

					iBasicVideo->Release();
				}
				iFilter->Release();
			}
			hr=iVideoWindow->put_FullScreenMode(OATRUE);
#endif

			/* // code to find all filter in the filter graph
			{
				IEnumFilters *iEnumFilters;
				pGraph->EnumFilters(&iEnumFilters);

				ULONG filterCount = 16;
				IFilter *iFilters[16];
				iEnumFilters->Next(filterCount, iFilters, &filterCount);

				for( ULONG j = 0; j < filterCount; ++j )
				{
					FILTER_INFO filterInfo;
					iFilters[j]->QueryFilterInfo(&filterInfo);
					filterInfo.pGraph->Release();
					iFilters[j]->Release();
				}

				iEnumFilters->Release();
			}*/

			iVideoWindow->HideCursor(OATRUE);
			iVideoWindow->put_Visible( OAFALSE );
			iVideoWindow->put_AutoShow( OAFALSE );
			LONG windowStyle;
			iVideoWindow->get_WindowStyle( &windowStyle);
			windowStyle &= ~WS_BORDER & ~WS_CAPTION & ~WS_SIZEBOX & ~WS_THICKFRAME &
				~WS_HSCROLL & ~WS_VSCROLL & ~WS_VISIBLE;
			iVideoWindow->put_WindowStyle( windowStyle);
		}
		else
			iVideoWindow = NULL;
		
		if( (hr = pGraph->QueryInterface(IID_IMediaControl, (void **) &pMC)) == 0)
		{
			pMC->Run();					// sometimes it returns 1, but still ok
			state = PLAYING;
			pMC->Release();
		}

		if( iVideoWindow )
		{
			iVideoWindow->put_Visible( OAFALSE );
			LONG windowStyle;
			iVideoWindow->get_WindowStyle( &windowStyle);
			windowStyle &= ~WS_BORDER & ~WS_CAPTION & ~WS_SIZEBOX & ~WS_THICKFRAME &
				~WS_HSCROLL & ~WS_VSCROLL & ~WS_VISIBLE;
			iVideoWindow->put_WindowStyle( windowStyle);

			LONG maxWidth;
			LONG maxHeight;
			hr=iVideoWindow->GetMaxIdealImageSize( &maxWidth, &maxHeight);
#ifdef FULL_SCREEN_VIDEO
#else
			iVideoWindow->put_BorderColor( RGB(0,0,0) );
			iVideoWindow->put_WindowState(SW_MAXIMIZE);

			IBaseFilter *iFilter;
			if( pGraph->FindFilterByName((const WCHAR *)L"Video Renderer", &iFilter) == 0)
			{
				IBasicVideo *iBasicVideo;
				if( iFilter->QueryInterface(IID_IBasicVideo, (void **)&iBasicVideo) == 0)
				{
					LONG screenWidth;
					LONG screenHeight;
					LONG videoWidth;
					LONG videoHeight;
					if( iVideoWindow->get_Width(&screenWidth) == 0 &&
						iVideoWindow->get_Height(&screenHeight) == 0 &&
						iBasicVideo->GetVideoSize(&videoWidth, &videoHeight) == 0)
					{
						// zoom in by 2 if possible
						if( screenWidth >= videoWidth * 2 &&
							screenHeight >= videoHeight * 2)
						{
							videoWidth *= 2;
							videoHeight *= 2;
						}

						// center the video client area
						iBasicVideo->SetDestinationPosition(
							(screenWidth-videoWidth)/2, (screenHeight-videoHeight)/2,
							videoWidth, videoHeight);
					}

					iBasicVideo->Release();
				}
				iFilter->Release();
			}
#endif
			iVideoWindow->HideCursor(OATRUE);
			iVideoWindow->SetWindowForeground(OATRUE);
		}

		if(iVideoWindow)
		{
			iVideoWindow->Release();
			iVideoWindow = NULL;
		}
	}

	if( hr && !skip_on_fail_flag)
		err.run("video.play error %d", hr );
}
Exemple #13
0
void BenchmarkSuite::run(
    const IFilter&      filter,
    BenchmarkResult&    suite_result) const
{
    BenchmarkingThreadContext benchmarking_context;
    bool has_begun_suite = false;

    for (size_t i = 0; i < impl->m_factories.size(); ++i)
    {
        IBenchmarkCaseFactory* factory = impl->m_factories[i];

        // Skip benchmark cases that aren't let through by the filter.
        if (!filter.accepts(factory->get_name()))
            continue;

        if (!has_begun_suite)
        {
            // Tell the listeners that a benchmark suite is about to be executed.
            suite_result.begin_suite(*this);
            suite_result.signal_suite_execution();
            has_begun_suite = true;
        }

        // Instantiate the benchmark case.
        unique_ptr<IBenchmarkCase> benchmark(factory->create());

        // Recreate the stopwatch (and the underlying timer) for every benchmark
        // case, since the CPU frequency will fluctuate quite a bit depending on
        // the CPU load.  We need an up-to-date frequency estimation in order to
        // compute accurate call rates.
        Impl::StopwatchType stopwatch(100000);

        // Tell the listeners that a benchmark case is about to be executed.
        suite_result.begin_case(*this, *benchmark.get());

#ifdef NDEBUG
        try
#endif
        {
            suite_result.signal_case_execution();

            // Estimate benchmarking parameters.
            const size_t measurement_count =
                Impl::compute_measurement_count(benchmark.get(), stopwatch);

            // Measure the overhead of calling IBenchmarkCase::run().
            const double overhead_ticks =
                Impl::measure_call_overhead_ticks(stopwatch, measurement_count);

            // Run the benchmark case.
            const double runtime_ticks =
                Impl::measure_runtime(
                    benchmark.get(),
                    stopwatch,
                    BenchmarkSuite::Impl::measure_runtime_ticks,
                    measurement_count);

#ifdef GENERATE_BENCHMARK_PLOTS
            vector<Vector2d> points;

            for (size_t j = 0; j < 100; ++j)
            {
                const double ticks =
                    Impl::measure_runtime(
                        benchmark.get(),
                        stopwatch,
                        BenchmarkSuite::Impl::measure_runtime_ticks,
                        max<size_t>(1, measurement_count / 100));
                points.emplace_back(
                    static_cast<double>(j),
                    ticks > overhead_ticks ? ticks - overhead_ticks : 0.0);
            }

            stringstream sstr;
            sstr << "unit benchmarks/plots/";
            sstr << get_name() << "_" << benchmark->get_name();
            sstr << ".gnuplot";

            GnuplotFile plotfile;
            plotfile.new_plot().set_points(points);
            plotfile.write(sstr.str());
#endif

            // Gather the timing results.
            TimingResult timing_result;
            timing_result.m_iteration_count = 1;
            timing_result.m_measurement_count = measurement_count;
            timing_result.m_frequency = static_cast<double>(stopwatch.get_timer().frequency());
            timing_result.m_ticks = runtime_ticks > overhead_ticks ? runtime_ticks - overhead_ticks : 0.0;

            // Post the timing result.
            suite_result.write(
                *this,
                *benchmark.get(),
                __FILE__,
                __LINE__,
                timing_result);
        }
#ifdef NDEBUG
        catch (const exception& e)
        {
            if (e.what()[0] != '\0')
            {
                suite_result.write(
                    *this,
                    *benchmark.get(),
                    __FILE__,
                    __LINE__,
                    "an unexpected exception was caught: %s",
                    e.what());
            }
            else
            {
                suite_result.write(
                    *this,
                    *benchmark.get(),
                    __FILE__,
                    __LINE__,
                    "an unexpected exception was caught (no details available).");
            }

            suite_result.signal_case_failure();
        }
        catch (...)
        {
            suite_result.write(
                *this,
                *benchmark.get(),
                __FILE__,
                __LINE__,
                "an unexpected exception was caught (no details available).");

            suite_result.signal_case_failure();
        }
#endif

        // Tell the listeners that the benchmark case execution has ended.
        suite_result.end_case(*this, *benchmark.get());
    }

    if (has_begun_suite)
    {
        // Report a benchmark suite failure if one or more benchmark cases failed.
        if (suite_result.get_case_failure_count() > 0)
            suite_result.signal_suite_failure();

        // Tell the listeners that the benchmark suite execution has ended.
        suite_result.end_suite(*this);
    }
}
Exemple #14
0
void run_test(IFilter &test, bool is_multi = true)
{
    test.insert(Criterion(BY_USERNAME, "4478901234568"));
    test.insert(Criterion(BY_IMEI, "1234567890123456"));
    test.insert(Criterion(BY_IMSI, "12345678901234"));
    test.insert(Criterion(BY_MSISDN, "4478901234567"));
    test.insert(Criterion(BY_MSISDN, "4478901234567"));

    (void) is_multi;    // release builds keep compiler happy
    assert( false == test.contains(Criterion(BY_MSISDN, "NOT ME")));
    assert( false == test.contains(Criterion(BY_IMEI, "4478901234567")));
    assert( false == test.contains(Criterion(BY_IMSI, "4478901234567")));
    assert( false == test.contains(Criterion(BY_USERNAME, "4478901234567")));

    assert( true == test.contains(Criterion(BY_IMEI, "1234567890123456")));
    assert( true == test.contains(Criterion(BY_IMSI, "12345678901234")));
    assert( false == test.contains(Criterion(BY_IMEI, "12345678901234")));
    assert( false == test.contains(Criterion(BY_IMSI, "1234567890123456")));

    assert( true == test.contains(Criterion(BY_USERNAME, "4478901234568")));
    assert( false == test.contains(Criterion(BY_MSISDN, "4478901234568")));

    assert( true == test.contains(Criterion(BY_MSISDN, "4478901234567")));
    assert( true == test.remove(Criterion(BY_MSISDN, "4478901234567")));
    assert( is_multi == test.contains(Criterion(BY_MSISDN, "4478901234567")));
    assert( is_multi == test.remove(Criterion(BY_MSISDN, "4478901234567")));
    assert( false == test.contains(Criterion(BY_MSISDN, "4478901234567")));
}
signed char
IFilterEndAnalyzer::analyze(AnalysisResult& idx, InputStream *in) {
    const string& filename = idx.fileName();
    int p = filename.find_last_of('.');
    if (p < 0 ||  extensions.find(filename.substr(p)) == extensions.end()) {
        return -1;
    }

    string filepath;
    bool fileisondisk = checkForFile(idx.depth(), filename);
    if (fileisondisk) {
        filepath = filename;
    } else {
        int p = filename.find_last_of(".");
        if ( p > 0 ){
            string ext = filename.substr(p).c_str();
            strlwr((char*)ext.c_str());
            p = ext.find_first_not_of("._abcdefghijklmnopqrstuvwxyz0123456789");
            if ( p >= 0 )
                filepath = writeToTempFile(in, "");
            else
                filepath = writeToTempFile(in, ext.c_str());
        }else
            filepath = writeToTempFile(in, "");

    }

    if (filepath.length() > 0) {

        IFilter* filter = NULL;
        void* pvfilter=NULL;

        wchar_t tmp[MAX_PATH];
        _cpycharToWide(tmp,filepath.c_str(),MAX_PATH);
        HRESULT hr = LoadIFilter(tmp,NULL,&pvfilter);
        if (hr == S_OK) {
            filter = (IFilter*)pvfilter;

            ULONG __i=0;
            hr = filter->Init(IFILTER_INIT_APPLY_INDEX_ATTRIBUTES,0,NULL,&__i);
            if (FAILED( hr )) {
                if (!fileisondisk)
                    unlink(filepath.c_str());
                return -1;
            }

            const int sbBufferLen = 1024;
            wchar_t sbBuffer[sbBufferLen];

            STAT_CHUNK ps;
            hr = filter->GetChunk(&ps);
            while ( SUCCEEDED(hr) ) {
                if (ps.flags == CHUNK_TEXT) {
                    int resultText = 0;

                    while ( resultText >= 0 ) {
                        ULONG sizeBuffer=sbBufferLen;
                        resultText = filter->GetText(&sizeBuffer, sbBuffer);
                        if (sizeBuffer > 0 ) {
                            string str = wchartoutf8(sbBuffer,sbBuffer+sizeBuffer);
                            idx.addText(str.c_str(),str.length());
                        }
                    }
                } else if ( ps.flags == CHUNK_VALUE ) {
                    PROPVARIANT *pVar;
                    while ( SUCCEEDED( hr = filter->GetValue( &pVar ) ) ) {
                        //printf("propid: %d\nkind:%d\n",ps.attribute.psProperty.propid,ps.attribute.psProperty.ulKind);
                        if ( ps.attribute.psProperty.propid == 2 &&
                             ps.attribute.psProperty.ulKind == 1 &&
                             pVar->vt == VT_LPWSTR ) {

                            string str = wchartoutf8(pVar->pwszVal,pVar->pwszVal+wcslen(pVar->pwszVal));
                            idx.addValue("title", str );
                        }
                        PropVariantClear( pVar );
                        CoTaskMemFree( pVar );
                    }
                } else {
                    printf("other flag %d\n",ps.flags);
                }
                hr = filter->GetChunk(&ps);
            }
            filter->Release();
            if (!fileisondisk)
                unlink(filepath.c_str());
            return 0;
        }


        DWORD dw = GetLastError();
        if ( dw != 0 ) {
            LPVOID lpMsgBuf;
            FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER |
                FORMAT_MESSAGE_FROM_SYSTEM,
                NULL,
                dw,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                (LPTSTR) &lpMsgBuf,
                0, NULL );

            wprintf(L"%s\n", lpMsgBuf);
            LocalFree(lpMsgBuf);
        }
    }
    if (!fileisondisk && filepath.length()>0) {
        unlink(filepath.c_str());
    }
    return -1;
}