void SCX_LogFile_Class_Provider::Invoke_GetMatchedRows()

in source/code/providers/SCX_LogFile_Class_Provider.cpp [128:273]


void SCX_LogFile_Class_Provider::Invoke_GetMatchedRows(
    Context& context,
    const String& nameSpace,
    const SCX_LogFile_Class& instanceName,
    const SCX_LogFile_GetMatchedRows_Class& in)
{
    /*
     * To return data, we have to post a single instance that contains an array of strings
     * MOF format: [OUT, ArrayType("Ordered")] string rows[]
     *
     * Here's some sample code that will do the trick:
     *
     * SCX_LogFile_GetMatchedRows_Class inst;
     * std::vector<mi::String> fakeData;
     *
     * fakeData.push_back( mi::String("data1") );
     * fakeData.push_back( mi::String("data2") );
     *
     * StringA rows(&fakeData[0], static_cast<MI_Uint32>(fakeData.size()));
     * inst.rows_value( rows );
     *
     * context.Post(inst);
     * context.Post(MI_RESULT_OK);
     */

    SCXCoreLib::SCXLogHandle log = SCXCore::g_LogFileProvider.GetLogHandle();
    SCX_LOGTRACE(log, L"LogFile Provider Invoke begin");

    SCX_PEX_BEGIN
    {
        SCXCoreLib::SCXThreadLock lock(SCXCoreLib::ThreadLockHandleGet(L"SCXCore::LogFileProvider::Lock"));

        // Validate that we have mandatory arguments
        if ( !in.filename_exists() || !in.regexps_exists() || !in.qid_exists() )
        {
            context.Post(MI_RESULT_INVALID_PARAMETER);
            return;
        }

        // Get the arguments:
        //   filename      : string
        //   regexps       : string array
        //   qid           : string
        //   elevationType : [Optional] string

        std::wstring filename = SCXCoreLib::StrFromMultibyte( in.filename_value().Str() );
        const StringA regexps_sa = in.regexps_value();
        std::wstring qid = SCXCoreLib::StrFromMultibyte( in.qid_value().Str() );
        std::wstring elevationType = SCXCoreLib::StrFromMultibyte( in.elevationType_value().Str() );

        bool fPerformElevation = false;
        if ( elevationType.length() )
        {
            if ( SCXCoreLib::StrToLower(elevationType) != L"sudo" )
            {
                context.Post(MI_RESULT_INVALID_PARAMETER);
                return;
            }

            fPerformElevation = true;
        }

        SCX_LOGTRACE(log, SCXCoreLib::StrAppend(L"SCXLogFileProvider::InvokeMatchedRows - filename = ", filename));
        SCX_LOGTRACE(log, SCXCoreLib::StrAppend(L"SCXLogFileProvider::InvokeMatchedRows - qid = ", qid));
        SCX_LOGTRACE(log, SCXCoreLib::StrAppend(L"SCXLogFileProvider::InvokeMatchedRows - regexp count = ", regexps_sa.GetSize()));
        SCX_LOGTRACE(log, SCXCoreLib::StrAppend(L"SCXLogFileProvider::InvokeMatchedRows - elevate = ", elevationType));

        // Extract and parse the regular expressions

        std::vector<SCXRegexWithIndex> regexps;
        std::wstring invalid_regex(L"");
            
        for (size_t i=0; i<regexps_sa.GetSize(); i++)
        {
            std::wstring regexp = SCXCoreLib::StrFromMultibyte(regexps_sa[static_cast<MI_Uint32>(i)].Str());

            SCX_LOGTRACE(log, StrAppend(L"SCXLogFileProvider::InvokeMatchedRows - regexp = ", regexp));

            try
            {
                SCXRegexWithIndex regind;
                regind.regex = new SCXRegex(regexp);
                regind.index = i;
                regexps.push_back(regind);
            }
            catch (SCXInvalidRegexException& e)
            {
                SCX_LOGWARNING(log, StrAppend(L"SCXLogFileProvider DoInvokeMethod - invalid regexp : ", regexp));
                invalid_regex = StrAppend(StrAppend(invalid_regex, invalid_regex.length()>0?L" ":L""), i);
            }
        }

        // We have to post a single instance that contains an array of strings
        // MOF format: [OUT, ArrayType("Ordered")] string rows[]
        std::vector<mi::String> returnData;

        // If any regular expressions with invalid syntax, add special row to result
        if (invalid_regex.length() > 0)
        {
            InsertOneString( context, returnData, StrAppend(L"InvalidRegexp;", invalid_regex));
        }

        SCX_LogFile_GetMatchedRows_Class inst;
        try
        {
            // Call helper function to get the data
            std::vector<std::wstring> matchedLines;
            bool bWasPartialRead = SCXCore::g_LogFileProvider.InvokeLogFileReader(
                filename, qid, regexps, fPerformElevation, matchedLines);

            // Add each match to the result property set
            //
            // Reserve space in the vector for efficiency:
            //   Current size + # of lines to add + 1 (for potential "MoreRowsAvailable")
            returnData.reserve( returnData.size() + matchedLines.size() + 1 );
            for (std::vector<std::wstring>::iterator it = matchedLines.begin();
                 it != matchedLines.end();
                 it++)
            {
                InsertOneString( context, returnData, *it );
            }

            // Set "MoreRowsAvailable" if we terminated early
            if (bWasPartialRead)
            {
                InsertOneString( context, returnData, L"MoreRowsAvailable;true" );
            }

            StringA rows(&returnData[0], static_cast<MI_Uint32>(returnData.size()));
            inst.rows_value( rows );
        }
        catch (SCXCoreLib::SCXFilePathNotFoundException& e)
        {
            SCX_LOGWARNING(log, SCXCoreLib::StrAppend(L"LogFileProvider DoInvokeMethod - File not found: ", filename).append(e.What()));
        }

        // Set the return value (the number of lines returned)
        inst.MIReturn_value( static_cast<MI_Uint32> (returnData.size()) );

        context.Post(inst);
        context.Post(MI_RESULT_OK);
    }
    SCX_PEX_END( L"SCX_LogFile_Class_Provider::Load", log );

    SCX_LOGTRACE(log, L"LogFile Provider Invoke end");
}