VirtualBox

Ignore:
Timestamp:
Oct 12, 2018 6:40:09 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125775
Message:

Main: bugref:9152 Implement the convertToStream API

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp

    r74354 r74822  
    23732373}
    23742374
     2375/**
     2376 * mediumio stream
     2377 */
     2378static RTEXITCODE handleMediumIOStream(HandlerArg *a, int iFirst, PMEDIUMIOCOMMONOPT pCommonOpts)
     2379{
     2380    /*
     2381     * Parse the options.
     2382     */
     2383    static const RTGETOPTDEF s_aOptions[] =
     2384    {
     2385        MEDIUMIOCOMMONOPT_DEFS(),
     2386        { "--output",   'O', RTGETOPT_REQ_STRING },
     2387        { "--format",   'F', RTGETOPT_REQ_STRING },
     2388        { "--variant",  'v', RTGETOPT_REQ_STRING }
     2389    };
     2390    const char *pszOutput = NULL;
     2391    MediumVariant_T enmMediumVariant = MediumVariant_Standard;
     2392    Bstr strFormat;
     2393
     2394    RTGETOPTSTATE GetState;
     2395    int rc = RTGetOptInit(&GetState, a->argc, a->argv, s_aOptions, RT_ELEMENTS(s_aOptions), iFirst, 0);
     2396    AssertRC(rc);
     2397    RTGETOPTUNION ValueUnion;
     2398    while ((rc = RTGetOpt(&GetState, &ValueUnion)) != 0)
     2399    {
     2400        switch (rc)
     2401        {
     2402            MEDIUMIOCOMMONOPT_CASES(pCommonOpts);
     2403
     2404            case 'O':
     2405                pszOutput = ValueUnion.psz;
     2406                break;
     2407            case 'F':
     2408                strFormat = ValueUnion.psz;
     2409                break;
     2410            case 'v':   // --variant
     2411            {
     2412                int vrc = parseMediumVariant(ValueUnion.psz, &enmMediumVariant);
     2413                if (RT_FAILURE(vrc))
     2414                    return errorArgument("Invalid medium variant '%s'", ValueUnion.psz);
     2415                break;
     2416            }
     2417
     2418            default:
     2419                return errorGetOpt(rc, &ValueUnion);
     2420        }
     2421    }
     2422
     2423    /*
     2424     * Open the medium for I/O.
     2425     */
     2426    ComPtr<IMediumIO>   ptrMediumIO;
     2427    uint64_t            cbMedium;
     2428    RTEXITCODE rcExit = mediumIOOpenMediumForIO(a, pCommonOpts, false /*fWritable*/, ptrMediumIO, &cbMedium);
     2429    if (rcExit == RTEXITCODE_SUCCESS)
     2430    {
     2431        /*
     2432         * Do we have an output file or do we write to stdout?
     2433         */
     2434        PRTSTREAM pOut = NULL;
     2435        if (pszOutput && (pszOutput[0] != '-' || pszOutput[1] != '\0'))
     2436        {
     2437            int vrc = RTStrmOpen(pszOutput, "wb", &pOut);
     2438            if (RT_FAILURE(vrc))
     2439                rcExit = RTMsgErrorExitFailure("Error opening '%s' for writing: %Rrc", pszOutput, vrc);
     2440        }
     2441        else
     2442        {
     2443            pOut = g_pStdOut;
     2444            RTStrmSetMode(pOut, true, -1);
     2445        }
     2446
     2447        if (rcExit == RTEXITCODE_SUCCESS)
     2448        {
     2449            ComPtr<IDataStream> ptrDataStream;
     2450            ComPtr<IProgress> ptrProgress;
     2451
     2452            com::SafeArray<MediumVariant_T> l_variants(sizeof(MediumVariant_T)*8);
     2453
     2454            for (ULONG i = 0; i < l_variants.size(); ++i)
     2455            {
     2456                ULONG temp = enmMediumVariant;
     2457                temp &= 1<<i;
     2458                l_variants [i] = (MediumVariant_T)temp;
     2459            }
     2460
     2461            HRESULT hrc = ptrMediumIO->ConvertToStream(strFormat.raw(), ComSafeArrayAsInParam(l_variants), 10 * _1M, ptrDataStream.asOutParam(), ptrProgress.asOutParam());
     2462            if (hrc == S_OK)
     2463            {
     2464                /* Read until we reached the end of the stream. */
     2465                for (;;)
     2466                {
     2467                    SafeArray<BYTE> SafeArrayBuf;
     2468
     2469                    hrc = ptrDataStream->Read(_64K, 0 /*Infinite wait*/, ComSafeArrayAsOutParam(SafeArrayBuf));
     2470                    if (   FAILED(hrc)
     2471                        || SafeArrayBuf.size() == 0)
     2472                        break;
     2473
     2474                    /* Output the data. */
     2475                    size_t const cbReturned = SafeArrayBuf.size();
     2476                    if (cbReturned)
     2477                    {
     2478                        BYTE const *pbBuf = SafeArrayBuf.raw();
     2479                        int vrc = VINF_SUCCESS;
     2480                        vrc = RTStrmWrite(pOut, pbBuf, cbReturned);
     2481                        if (RT_FAILURE(vrc))
     2482                        {
     2483                            rcExit = RTMsgErrorExitFailure("Error writing to '%s': %Rrc", pszOutput, vrc);
     2484                            break;
     2485                        }
     2486                    }
     2487
     2488                    /** @todo: Check progress. */
     2489                }
     2490            }
     2491            else
     2492            {
     2493                com::GlueHandleComError(ptrMediumIO, "ConvertToStream()", hrc, __FILE__, __LINE__);
     2494                rcExit = RTEXITCODE_FAILURE;
     2495            }
     2496
     2497            /*
     2498             * Close output.
     2499             */
     2500            if (pOut != g_pStdOut)
     2501            {
     2502                int vrc = RTStrmClose(pOut);
     2503                if (RT_FAILURE(vrc))
     2504                    rcExit = RTMsgErrorExitFailure("Error closing '%s': %Rrc", pszOutput, vrc);
     2505            }
     2506            else
     2507                RTStrmSetMode(pOut, false, -1);
     2508        }
     2509    }
     2510    return rcExit;
     2511}
     2512
    23752513
    23762514RTEXITCODE handleMediumIO(HandlerArg *a)
     
    23852523        { "formatfat",  1000, RTGETOPT_REQ_NOTHING },
    23862524        { "cat",        1001, RTGETOPT_REQ_NOTHING },
     2525        { "stream",     1002, RTGETOPT_REQ_NOTHING },
    23872526    };
    23882527    MEDIUMIOCOMMONOPT   CommonOpts = { NULL, DeviceType_Null, NULL };
     
    24052544                setCurrentSubcommand(HELP_SCOPE_MEDIUMIO_CAT);
    24062545                return handleMediumIOCat(a, GetState.iNext, &CommonOpts);
     2546            case 1002:
     2547                setCurrentSubcommand(HELP_SCOPE_MEDIUMIO_STREAM);
     2548                return handleMediumIOStream(a, GetState.iNext, &CommonOpts);
    24072549
    24082550            case VINF_GETOPT_NOT_OPTION:
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette