/**
 * Benchmark RTCrc routines potentially relevant for SSM or PGM - All in one go.
 *
 * @param  pabSrc   Pointer to the test data.
 * @param  cbSrc    The size of the test data.
 */
static void tstBenchmarkCRCsAllInOne(uint8_t const *pabSrc, size_t cbSrc)
{
    RTPrintf("Algorithm     Speed                  Time      Digest\n"
             "------------------------------------------------------------------------------\n");

    uint64_t NanoTS = RTTimeNanoTS();
    uint32_t u32Crc = RTCrc32(pabSrc, cbSrc);
    NanoTS = RTTimeNanoTS() - NanoTS;
    unsigned uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("CRC-32    %'9u KB/s  %'15llu ns - %08x\n", uSpeed, NanoTS, u32Crc);


    NanoTS = RTTimeNanoTS();
    uint64_t u64Crc = RTCrc64(pabSrc, cbSrc);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("CRC-64    %'9u KB/s  %'15llu ns - %016llx\n", uSpeed, NanoTS, u64Crc);

    NanoTS = RTTimeNanoTS();
    u32Crc = RTCrcAdler32(pabSrc, cbSrc);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("Adler-32  %'9u KB/s  %'15llu ns - %08x\n", uSpeed, NanoTS, u32Crc);

    NanoTS = RTTimeNanoTS();
    uint8_t abMd5Hash[RTMD5HASHSIZE];
    RTMd5(pabSrc, cbSrc, abMd5Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    char szDigest[257];
    RTMd5ToString(abMd5Hash, szDigest, sizeof(szDigest));
    RTPrintf("MD5       %'9u KB/s  %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);

    NanoTS = RTTimeNanoTS();
    uint8_t abSha1Hash[RTSHA1_HASH_SIZE];
    RTSha1(pabSrc, cbSrc, abSha1Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTSha1ToString(abSha1Hash, szDigest, sizeof(szDigest));
    RTPrintf("SHA-1     %'9u KB/s  %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);

    NanoTS = RTTimeNanoTS();
    uint8_t abSha256Hash[RTSHA256_HASH_SIZE];
    RTSha256(pabSrc, cbSrc, abSha256Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTSha256ToString(abSha256Hash, szDigest, sizeof(szDigest));
    RTPrintf("SHA-256   %'9u KB/s  %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);

    NanoTS = RTTimeNanoTS();
    uint8_t abSha512Hash[RTSHA512_HASH_SIZE];
    RTSha512(pabSrc, cbSrc, abSha512Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTSha512ToString(abSha512Hash, szDigest, sizeof(szDigest));
    RTPrintf("SHA-512   %'9u KB/s  %'15llu ns - %s\n", uSpeed, NanoTS, szDigest);
}
void UIDownloaderExtensionPack::handleDownloadedObject(UINetworkReply *pReply)
{
    /* Read received data into the buffer: */
    QByteArray receivedData(pReply->readAll());
    /* Serialize that buffer into the file: */
    while (true)
    {
        /* Try to open file for writing: */
        QFile file(target());
        if (file.open(QIODevice::WriteOnly))
        {
            /* Write buffer into the file: */
            file.write(receivedData);
            file.close();

            /* Calc the SHA-256 on the bytes, creating a string: */
            uint8_t abHash[RTSHA256_HASH_SIZE];
            RTSha256(receivedData.constData(), receivedData.length(), abHash);
            char szDigest[RTSHA256_DIGEST_LEN + 1];
            int rc = RTSha256ToString(abHash, szDigest, sizeof(szDigest));
            if (RT_FAILURE(rc))
            {
                AssertRC(rc);
                szDigest[0] = '\0';
            }

            /* Warn the listener about extension-pack was downloaded: */
            emit sigDownloadFinished(source().toString(), target(), &szDigest[0]);
            break;
        }

        /* Warn the user about extension-pack was downloaded but was NOT saved: */
        msgCenter().warnAboutExtentionPackCantBeSaved(GUI_ExtPackName, source().toString(), QDir::toNativeSeparators(target()));

        /* Ask the user for another location for the extension-pack file: */
        QString strTarget = QIFileDialog::getExistingDirectory(QFileInfo(target()).absolutePath(),
                                                               msgCenter().networkManagerOrMainWindowShown(),
                                                               tr("Select folder to save %1 to").arg(GUI_ExtPackName), true);

        /* Check if user had really set a new target: */
        if (!strTarget.isNull())
            setTarget(QDir(strTarget).absoluteFilePath(QFileInfo(target()).fileName()));
        else
            break;
    }
}
/**
 * Benchmark RTCrc routines potentially relevant for SSM or PGM - Page by page.
 *
 * @param  pabSrc   Pointer to the test data.
 * @param  cbSrc    The size of the test data.
 */
static void tstBenchmarkCRCsPageByPage(uint8_t const *pabSrc, size_t cbSrc)
{
    RTPrintf("Algorithm     Speed                  Time     \n"
             "----------------------------------------------\n");

    size_t const cPages = cbSrc / PAGE_SIZE;

    uint64_t NanoTS = RTTimeNanoTS();
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTCrc32(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE);
    NanoTS = RTTimeNanoTS() - NanoTS;
    unsigned uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("CRC-32    %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);


    NanoTS = RTTimeNanoTS();
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTCrc64(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("CRC-64    %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);

    NanoTS = RTTimeNanoTS();
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTCrcAdler32(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("Adler-32  %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);

    NanoTS = RTTimeNanoTS();
    uint8_t abMd5Hash[RTMD5HASHSIZE];
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTMd5(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abMd5Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("MD5       %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);

    NanoTS = RTTimeNanoTS();
    uint8_t abSha1Hash[RTSHA1_HASH_SIZE];
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTSha1(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abSha1Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("SHA-1     %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);

    NanoTS = RTTimeNanoTS();
    uint8_t abSha256Hash[RTSHA256_HASH_SIZE];
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTSha256(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abSha256Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("SHA-256   %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);

    NanoTS = RTTimeNanoTS();
    uint8_t abSha512Hash[RTSHA512_HASH_SIZE];
    for (uint32_t iPage = 0; iPage < cPages; iPage++)
        RTSha512(&pabSrc[iPage * PAGE_SIZE], PAGE_SIZE, abSha512Hash);
    NanoTS = RTTimeNanoTS() - NanoTS;
    uSpeed = (unsigned)(cbSrc / (long double)NanoTS * 1000000000.0 / 1024);
    RTPrintf("SHA-512   %'9u KB/s  %'15llu ns\n", uSpeed, NanoTS);
}