Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read scenario fixed #2

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/fcurl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ size_t fcurl_read(void *ptr, size_t size, size_t nmemb, FCURL *stream);
size_t fcurl_write(const void *ptr, size_t size, size_t nmemb,
FCURL *stream);
int fcurl_flush(FCURL *stream);
int fcurl_eof(FCURL *stream);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't really "fix the read scenario" but is unrelated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, possibly mixed up with PR title that gets all the changes, the commit says "Provides a definition for fcurl_feof", which was missing. Should have made 2 PRs!

int fcurl_close(FCURL *stream);
int fcurl_getc(FCURL *stream);
char *fcurl_gets(char *s, int size, FCURL *stream);
Expand Down
71 changes: 23 additions & 48 deletions src/fcurl.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,50 +40,32 @@ static size_t write_callback(char *buffer, size_t size, size_t nitems,

osize = size; /* keep the original input size for returning */

n_remaining = h->b.size - h->b.used; /* remaining space in private buffer */
n_remainuser = h->user.size - h->user.used; /* remaining space in user buffer */
buffer += h->used;
size -= h->used;

if(n_remainuser) {
size_t n_copytouser = MIN(size, n_remainuser);

/* space left in the user buffer, copy as much as possible to there */
memcpy(h->user.p, buffer, n_copytouser);
memcpy(h->user.p + h->user.used, buffer, n_copytouser);

buffer += n_copytouser;
size -= n_copytouser;

h->user.used += n_copytouser;
}

if(!size)
if(!size) {
/* all data is taken care of */
h->used = 0;
return osize;

if(size > n_remaining) {
char *newp;
size_t n_missing = (size - n_remaining);

/* we will have reaons to go back and reconsider buffer growth algorithms
later */
size_t newsize = h->b.size + n_missing + BUFFERGROWTHMARGIN;

newp = realloc(h->b.p, newsize);
if(!newp) {
/* use fprintf() during intial debugging */
fprintf(stderr, "out of memory!\n");
return 0; /* makes the transfer fail */
}
else {
h->b.size = newsize;
h->b.p = newp;
}
}

/* copy data from libcurl into our handle specific buffer */
memcpy(&h->b.p[h->b.used], buffer, size);
h->b.used += size;

return osize;
/* Excess data, pause the transfer, storing how much is already used */
h->used = osize - size;
h->paused = true;
return CURL_WRITEFUNC_PAUSE;
}

/*
Expand All @@ -98,25 +80,20 @@ static int transfer(struct fcurl_handle *h, const void *target, size_t max)
h->user.used = 0;
h->user.size = max;

if(h->b.used) {
/* there is data left from the previous invoke */
size_t n_copytouser = MIN(h->b.used, max);
memcpy((char *)target, h->b.p, n_copytouser);
h->user.used += n_copytouser;

/* slide the remaining buffer to the beginning */
memmove(h->b.p, h->b.p+n_copytouser, h->b.used - n_copytouser);
h->b.used -= n_copytouser;

if(h->user.used == max)
return 0;
}
else if(h->transfer_complete)
if(h->transfer_complete)
return 1; /* no buffer data left and transfer complete == done */

if(!h->transfer_complete) {
do {
mc = curl_multi_wait(h->mh, NULL, 0, 5000, &numfds);
if (h->paused) {
/* Unpause + no 'wait' because it was paused with excess data */
h->paused = false;
curl_easy_pause(h->curl, CURLPAUSE_CONT);
mc = CURLM_OK;
}
else {
mc = curl_multi_wait(h->mh, NULL, 0, 5000, &numfds);
}
if(mc == CURLM_OK) {
int left;
struct CURLMsg *m;
Expand Down Expand Up @@ -196,19 +173,17 @@ int fcurl_close(struct fcurl_handle *h)
/* cleanup */
curl_easy_cleanup(h->curl);

free(h->b.p);
curl_multi_cleanup(h->mh);

free(h);

return ret;
}

int fcurl_eof(struct fcurl_handle *h)
{
int ret=0;

/* add code here */

return ret;
/* Still does not make difference between EOF and errors */
return h->transfer_complete;
}

/*
Expand Down
3 changes: 2 additions & 1 deletion src/handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ struct buffer {
struct fcurl_handle {
CURL *curl;
CURLM *mh;
bool paused;
size_t used; /* used in callback buffer before pausing */
bool transfer_complete;
CURLcode transfer_rc; /* assigned after completed transfer */
struct buffer b; /* allocated and handled internally */
struct buffer user; /* as provided by the application */
};

Expand Down