Add a download Callback in URL class


#1

Hi jules,

I need a callback during a download process, so I added some codes to the URL class and it can now work to my anticipation. Just want to know if you want to add a callback like this in the current juce.

What I did is simply reusing the OpenStreamCallback you made for POST… Storing the callback and the context and using them in the read(xx,xx) function in juce_mac_Network.mm

bool start (URL::OpenStreamProgressCallback* callback, void* context)
    {
        testCallback = callback;
        testCallbackCtx = context;
        
        startThread();

        while (isThreadRunning() && ! initialised)
        {
            if (callback != nullptr)
                callback (context, -1, (int) [[request HTTPBody] length]);

            Thread::sleep (1);
        }

        return connection != nil && ! hasFailed;
    }
int read (char* dest, int numBytes)
    {
        int numDone = 0;

        while (numBytes > 0)
        {
            const int available = jmin (numBytes, (int) [data length]);

            if (available > 0)
            {
                const ScopedLock sl (dataLock);
                [data getBytes: dest length: (NSUInteger) available];
                [data replaceBytesInRange: NSMakeRange (0, (NSUInteger) available) withBytes: nil length: 0];

                numDone += available;
                numBytes -= available;
                dest += available;
                
                testCallback(testCallbackCtx, available, thisVaribleSeemsUseless);
            }
            else
            {
                if (hasFailed || hasFinished)
                    break;

                Thread::sleep (1);
            }
        }

        return numDone;
    }

and of course

URL::OpenStreamProgressCallback* testCallback;
void *testCallbackCtx;

Hope I can see an official codes for this?

Thanks


#2

Ok, thanks, I’ll take a look!


#3

ok, sorry, this really doesn’t make any sense to me…

That callback is designed for giving feedback while the stream is being opened - the callback object will probably have been deleted when you try to call it later during a read call! And the callback was never designed to receive the total number of bytes that have been read during the stream’s lifetime, so how could it make sense to call it for that? Surely you can just keep a byte count yourself when your code that calls read() ?


#4

Hi jules,

  1. Yes I am keeping a byte count of how many bytes I have read at somewhere else;

  2. the code listed above indeed is dangerous since the callback could be nullptr, I have added a if (nullptr) check before calling the callback now.

Anyway, I just think it is quite straightforward and easy to add a download callback in this class, especially for you do that.

thx.


#5

Please read my comment again - there are much more serious problems with your code than a null pointer!

And like I said, it really doesn’t make any sense: this callback is not designed to be used in the way you’re using it!