views:

24

answers:

2

I'm curious why I'm having trouble with this function. I'm downloading a PNG file on the web to a destination path. For example, downloading the Google image to the C: drive:

netDownloadData("http://www.google.com/intl/en_ALL/images/srpr/logo1w.png", "c:\file.png");

The file size is correct after downloading. Nothing returning false. When I try opening it it won't show the image. Any ideas are helpful. Thanks!

Here's the code:

bool netDownloadData(const char *strSourceUrl, const char *strDestPath)
{

         HINTERNET hINet = NULL;
    HINTERNET hFile = NULL;
    char buffer[1024];
    DWORD dwRead;
    String sTemp;
    FILE *fp = NULL;
    DWORD size = 0;

    // Open a new internet session
    hINet = netInit();
    if (hINet == NULL) {
        sprintf(buffer, "Initializing WinINet failed.", strSourceUrl);
        utilLog(buffer);
        netCloseHandle(hINet);
        return false;
    }

    // Open the requested url.
    hFile = netOpenUrl(hINet, strSourceUrl);
    if (hFile == NULL) {
        sprintf(buffer, "URL failed upon loading: %s\n", strSourceUrl);
        utilLog(buffer);
        netCloseHandle(hINet);
        return false;
    }

    // Read file.
    while (InternetReadFile(hFile, buffer, 1023, &dwRead))
    {
        if (dwRead == 0)
            break;

        buffer[dwRead] = 0;

        sTemp += buffer;
        size += dwRead;
    }

    // Load information to file. 
    fp = fopen(strDestPath, "wb");
    if (fp == NULL)
        return false;

    fwrite(sTemp, size, 1, fp);
    fclose(fp); 

    InternetCloseHandle(hFile);
    InternetCloseHandle(hINet);

    return true;
}
A: 

It looks like your second and third args to fwrite are transposed. See fwrite docs for explanation.

try:

fwrite(sTemp, 1, size, fp);
John Weldon
I don't think the order really matters, it finally just writes `size * count` bytes from the starting location.
casablanca
@casablanca Interesting that the order doesn't matter? Seems like relying on an implementation detail though... Nice catch on the `String`, that was another issue I was wondering about.
John Weldon
It's used interchangeably in the reference page you gave. The prototype is correct but the example is wrong (if it's teaching how to use the function as is in the prototype). It should be updated. Not the end fo the world though.
Phil
@John Weldon: I believe it's actually standard behaviour, although I don't know why `fread` and `fwrite` were defined that way.
casablanca
Previous question on here about the reasoning of those parameters: http://stackoverflow.com/questions/295994/what-is-the-rationale-for-fread-fwrite-taking-size-and-count-as-arguments
TheUndeadFish
+1  A: 

What data type is String? Avoid storing binary data in strings because NULLs in the data can potentially cause problems. Just write the buffer as and when you read it:

// Load information to file. 
fp = fopen(strDestPath, "wb");
if (fp == NULL)
    return false;

// Read file.
while (InternetReadFile(hFile, buffer, 1024, &dwRead))
{
    if (dwRead == 0)
        break;

    fwrite(buffer, dwRead, 1, fp);
}

fclose(fp); 
casablanca
Worked great. Thanks!
Phil