GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Description: a tiny graphical app kit for ruby
Homepage: http://code.whytheluckystiff.net/shoes
Clone URL: git://github.com/why/shoes.git
 * shoes/http/curl.c: okay, the curl binding is sending each of the events 
 i'll be hooking into.
 * shoes/http.h: expanded the event structure to include different stages 
 of the transfer and added an HTTP_EVENT macro for calling the handler on 
 each platform.
why (author)
Thu Jul 17 16:14:42 -0700 2008
commit  ac30e4c672eba810100658ab3accaed811b82218
tree    3b24ef99a0318e77d795535ae80af0f65504df3b
parent  fbc8bbb0cfefff76d5e1ba008b8b3de57c6f5a96
...
56
57
58
59
 
60
61
62
...
56
57
58
 
59
60
61
62
0
@@ -56,7 +56,7 @@ class Shoes
0
     
0
     opts.on("-d", "--download",
0
             "A download test") do
0
- str = download_non_threaded "http://hacketyhack.net/pkg/win32/shoes"
0
+ str = download_and_wait "http://hacketyhack.net/pkg/win32/shoes"
0
       raise SystemExit, str
0
     end
0
 
...
8
9
10
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
13
14
...
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
0
@@ -8,7 +8,21 @@
0
 #define SHOES_DOWNLOAD_CONTINUE 0
0
 #define SHOES_DOWNLOAD_HALT 1
0
 
0
+#define SHOES_HTTP_CONNECTED 5
0
+#define SHOES_HTTP_TRANSFER 10
0
+#define SHOES_HTTP_COMPLETED 15
0
+
0
+#define HTTP_EVENT(handler, s, perc, trans, tot, dat, abort) \
0
+{ shoes_download_event event; \
0
+ event.stage = s; \
0
+ event.percent = perc; \
0
+ event.transferred = trans;\
0
+ event.total = tot; \
0
+ if (handler != NULL && (handler(&event, dat) & SHOES_DOWNLOAD_HALT)) \
0
+ { abort; } }
0
+
0
 typedef struct {
0
+ unsigned char stage;
0
   unsigned long long total;
0
   unsigned long long transferred;
0
   unsigned int percent;
...
16
17
18
19
20
21
22
23
24
25
26
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
29
30
 
31
32
33
...
39
40
41
42
 
43
44
45
46
47
48
49
50
51
52
 
 
53
54
55
...
60
61
62
63
64
 
65
66
67
68
69
70
71
72
73
74
75
76
 
 
 
 
 
 
77
78
79
80
81
 
 
82
83
84
 
 
85
86
 
87
88
89
 
90
91
92
93
 
 
 
 
94
95
96
 
 
97
98
99
...
16
17
18
 
 
 
 
 
19
20
21
 
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
42
43
44
45
...
51
52
53
 
54
55
56
 
 
 
 
 
 
 
 
57
58
59
60
61
...
66
67
68
 
 
69
70
71
72
73
74
75
 
 
 
 
 
 
76
77
78
79
80
81
82
83
84
 
 
85
86
87
88
89
90
91
92
 
93
94
95
 
96
97
98
99
 
100
101
102
103
104
 
 
105
106
107
108
109
0
@@ -16,18 +16,30 @@
0
 #include <curl/easy.h>
0
 
0
 typedef struct {
0
- shoes_download_handler handler;
0
- void *data;
0
-} shoes_curl_progress_data;
0
-
0
-typedef struct {
0
   char *mem;
0
   FILE *fp;
0
   size_t size;
0
-} shoes_curl_write_data;
0
+ size_t total;
0
+ shoes_download_handler handler;
0
+ void *data;
0
+} shoes_curl_data;
0
+
0
+const char *content_len_str = "Content-Length: ";
0
+
0
+size_t
0
+shoes_curl_header_funk(void *ptr, size_t size, size_t nmemb, shoes_curl_data *data)
0
+{
0
+ size_t realsize = size * nmemb;
0
+ if (strncmp(ptr, content_len_str, strlen(content_len_str)) == 0)
0
+ {
0
+ data->total = strtoll(ptr + strlen(content_len_str), NULL, 10);
0
+ HTTP_EVENT(data->handler, SHOES_HTTP_CONNECTED, 0, 0, data->total, data->data, return -1);
0
+ }
0
+ return realsize;
0
+}
0
 
0
 size_t
0
-shoes_curl_write_funk(void *ptr, size_t size, size_t nmemb, shoes_curl_write_data *data)
0
+shoes_curl_write_funk(void *ptr, size_t size, size_t nmemb, shoes_curl_data *data)
0
 {
0
   size_t realsize = size * nmemb;
0
   if (data->mem != NULL)
0
@@ -39,17 +51,11 @@ shoes_curl_write_funk(void *ptr, size_t size, size_t nmemb, shoes_curl_write_dat
0
 }
0
 
0
 int
0
-shoes_curl_progress_funk(shoes_curl_progress_data *data,
0
+shoes_curl_progress_funk(shoes_curl_data *data,
0
   double dltotal, double dlnow, double ultotal, double ulnow)
0
 {
0
- shoes_download_event event;
0
- event.percent = dlnow * 100.0 / dltotal;
0
- event.transferred = dlnow;
0
- event.total = dltotal;
0
-
0
- if (data->handler != NULL && (data->handler(&event, data->data) & SHOES_DOWNLOAD_HALT))
0
- return 1;
0
-
0
+ HTTP_EVENT(data->handler, SHOES_HTTP_TRANSFER, dlnow * 100.0 / dltotal, dlnow,
0
+ dltotal, data->data, return 1);
0
   return 0;
0
 }
0
 
0
@@ -60,40 +66,44 @@ shoes_download(char *host, int port, char *path, char *mem, char *filepath,
0
   char url[SHOES_BUFSIZE], uagent[SHOES_BUFSIZE];
0
   CURL *curl = curl_easy_init();
0
   CURLcode res;
0
- shoes_curl_progress_data progress_data;
0
- shoes_curl_write_data write_data;
0
+ shoes_curl_data cdata;
0
   if (curl == NULL) return;
0
 
0
   sprintf(url, "http://%s:%d/%s", host, port, path);
0
   sprintf(uagent, "Shoes/0.r%d (%s) %s/%d", SHOES_REVISION, SHOES_PLATFORM,
0
     SHOES_RELEASE_NAME, SHOES_BUILD_DATE);
0
 
0
- progress_data.handler = handler;
0
- progress_data.data = data;
0
-
0
- write_data.mem = mem;
0
- write_data.fp = NULL;
0
- write_data.size = 0;
0
+ cdata.mem = mem;
0
+ cdata.fp = NULL;
0
+ cdata.size = 0;
0
+ cdata.total = 0;
0
+ cdata.handler = handler;
0
+ cdata.data = data;
0
 
0
   if (mem == NULL)
0
   {
0
- write_data.fp = fopen(filepath, "wb");
0
- if (write_data.fp == NULL) return;
0
+ cdata.fp = fopen(filepath, "wb");
0
+ if (cdata.fp == NULL) return;
0
   }
0
 
0
   curl_easy_setopt(curl, CURLOPT_URL, url);
0
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, shoes_curl_header_funk);
0
+ curl_easy_setopt(curl, CURLOPT_WRITEHEADER, &cdata);
0
   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, shoes_curl_write_funk);
0
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_data);
0
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &cdata);
0
   curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
0
   curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, shoes_curl_progress_funk);
0
- curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &progress_data);
0
+ curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, &cdata);
0
   curl_easy_setopt(curl, CURLOPT_USERAGENT, uagent);
0
 
0
   res = curl_easy_perform(curl);
0
- *size = write_data.size;
0
+ *size = cdata.total;
0
+
0
+ HTTP_EVENT(handler, SHOES_HTTP_TRANSFER, 100, cdata.total, cdata.total, data, 1);
0
+ HTTP_EVENT(handler, SHOES_HTTP_COMPLETED, 100, cdata.total, cdata.total, data, 1);
0
 
0
- if (write_data.fp != NULL)
0
- fclose(write_data.fp);
0
+ if (cdata.fp != NULL)
0
+ fclose(cdata.fp);
0
 
0
   curl_easy_cleanup(curl);
0
 }
...
3617
3618
3619
 
 
 
 
 
 
 
3620
3621
3622
...
4278
4279
4280
4281
 
4282
...
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
...
4285
4286
4287
 
4288
4289
0
@@ -3617,6 +3617,13 @@ shoes_msg(ID typ, VALUE str)
0
     shoes_msg(s_##t, rb_str_new2(buf)); \
0
   }
0
 
0
+int
0
+shoes_dont_handler(shoes_download_event *de, void *data)
0
+{
0
+ printf("EVENT: %d, %lu, %llu, %llu\n", (int)de->stage, de->percent,
0
+ de->transferred, de->total);
0
+}
0
+
0
 VALUE
0
 shoes_download_non_threaded(VALUE self, VALUE url)
0
 {
0
@@ -4278,5 +4285,5 @@ shoes_ruby_init()
0
   rb_define_method(rb_mKernel, "ask_save_file", CASTHOOK(shoes_dialog_save), 0);
0
   rb_define_method(rb_mKernel, "ask_open_folder", CASTHOOK(shoes_dialog_open_folder), 0);
0
   rb_define_method(rb_mKernel, "ask_save_folder", CASTHOOK(shoes_dialog_save_folder), 0);
0
- rb_define_method(rb_mKernel, "download_non_threaded", CASTHOOK(shoes_download_non_threaded), 1);
0
+ rb_define_method(rb_mKernel, "download_and_wait", CASTHOOK(shoes_download_non_threaded), 1);
0
 }

Comments

    No one has commented yet.