1 /*
2  *
3  *   Copyright (C) 2012-2018 by C.H. Huang
4  *   plushuang.tw@gmail.com
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2.1 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  *  ---
21  *
22  *  In addition, as a special exception, the copyright holders give
23  *  permission to link the code of portions of this program with the
24  *  OpenSSL library under certain conditions as described in each
25  *  individual source file, and distribute linked combinations
26  *  including the two.
27  *  You must obey the GNU Lesser General Public License in all respects
28  *  for all of the code used other than OpenSSL.  If you modify
29  *  file(s) with this exception, you may extend this exception to your
30  *  version of the file(s), but you are not obligated to do so.  If you
31  *  do not wish to do so, delete this exception statement from your
32  *  version.  If you delete this exception statement from all source
33  *  files in the program, then also delete it here.
34  *
35  */
36 
37 #include <stdio.h>
38 #include <string.h>
39 #include <UgArray.h>
40 #include <UgetNode.h>
41 
42 #include <UgJson.h>
43 #include <UgString.h>
44 #include <UgGroupData.h>
45 #include <UgetFiles.h>
46 //#include <UgetPlugin.h>
47 
48 #include <UgetA2cf.h>
49 #include <UgetCurl.h>
50 #include <UgetRss.h>
51 #include <UgetMedia.h>
52 #include <UgetSequence.h>
53 
54 // ----------------------------------------------------------------------------
55 // UgetNode
56 
57 UgEntry	NodeChildrenEntry[] = {
58 	{NULL, 0, UG_ENTRY_ARRAY,
59 			(UgJsonParseFunc) ug_json_parse_uget_node_children,
60 			(UgJsonWriteFunc) ug_json_write_uget_node_children},
61 	{NULL}
62 };
63 
init_node(UgetNode * parent)64 void init_node (UgetNode* parent)
65 {
66 	UgetNode*  newone;
67 	UgetNode*  newtwo;
68 
69 	newone = uget_node_new (NULL);
70 	uget_node_append (parent, newone);
71 	newtwo = uget_node_new (NULL);
72 	uget_node_append (parent, newtwo);
73 
74 	parent = newtwo;
75 	newone = uget_node_new (NULL);
76 	uget_node_append (parent, newone);
77 	newtwo = uget_node_new (NULL);
78 	uget_node_append (parent, newtwo);
79 }
80 
81 // "01-03-02"
dump_int_array(UgArrayInt * array)82 void dump_int_array (UgArrayInt* array)
83 {
84 	int  index;
85 
86 	for (index = 0;  index < array->length;  index++) {
87 		if (index)
88 			printf ("-");
89 		printf ("%.2d", array->at[index]);
90 	}
91 	puts ("");
92 }
93 
dump_fake_path(UgetNode * node,UgArrayInt * array)94 void dump_fake_path (UgetNode* node, UgArrayInt* array)
95 {
96 	UgetNode*   cur;
97 	int         index;
98 
99 	for (index = 0, cur = node->fake;  cur;  cur = cur->peer, index++) {
100 		*(int*) ug_array_alloc(array, 1) = index;
101 		dump_int_array (array);
102 		dump_fake_path (cur, array);
103 		array->length--;
104 	}
105 }
106 
print_fake_path(UgetNode * node)107 void print_fake_path (UgetNode* node)
108 {
109 	UgArrayInt  array;
110 	ug_array_init(&array, sizeof (int), 20);
111 	dump_fake_path (node, &array);
112 	ug_array_clear (&array);
113 }
114 
test_fake_path()115 void test_fake_path ()
116 {
117 	UgetNode*  node;
118 	UgetNode*  fake0;
119 	UgetNode*  fake1;
120 	UgetNode*  fake2;
121 
122 	node = uget_node_new (NULL);
123 	fake0 = uget_node_new (node);
124 	fake1 = uget_node_new (node);
125 	fake2 = uget_node_new (node);
126 
127 	uget_node_new (fake0);
128 
129 	uget_node_new (fake1);
130 	uget_node_new (fake1);
131 
132 	uget_node_new (fake2);
133 	uget_node_new (fake2);
134 	uget_node_new (fake2);
135 
136 	print_fake_path (node);
137 
138 	uget_node_free (node);
139 }
140 
parse_node(UgetNode * parent)141 void parse_node (UgetNode* parent)
142 {
143 	int     code;
144 	UgJson  json;
145 	const char* json_string = {
146 		"["
147 		"  {"
148 		"    \"name\": null,"
149 		"    \"type\": 1,"
150 		"    \"info\": {"
151 		"    },"
152 		"    \"children\": ["
153 		"    ]"
154 		"  },"
155 		"  {"
156 		"    \"name\": null,"
157 		"    \"type\": 2,"
158 		"    \"info\": {"
159 		"    },"
160 		"    \"children\": ["
161 		"      {"
162 		"        \"name\": null,"
163 		"        \"type\": 3,"
164 		"        \"info\": {"
165 		"        },"
166 		"        \"children\": ["
167 		"        ]"
168 		"      },"
169 		"      {"
170 		"        \"name\": null,"
171 		"        \"type\": 4,"
172 		"        \"info\": {"
173 		"        },"
174 		"        \"children\": ["
175 		"        ]"
176 		"      }"
177 		"    ]"
178 		"  }"
179 		"]"
180 	};
181 
182 	ug_json_init (&json);
183 	ug_json_begin_parse (&json);
184 #if 1
185 	// method 1: use UgEntry to parse start of array
186 	ug_json_push (&json, ug_json_parse_entry, parent, NodeChildrenEntry);
187 #else
188 	// method 2: push ug_json_parse_array() to parse start of array
189 	ug_json_push (&json, ug_json_parse_uget_node_children, parent, NULL);
190 	ug_json_push (&json, ug_json_parse_array, NULL, NULL);
191 #endif
192 	code = ug_json_parse (&json, json_string, -1);
193 	printf ("ug_json_parse response %d\n", code);
194 	code = ug_json_end_parse (&json);
195 	printf ("ug_json_end_parse response %d\n", code);
196 	ug_json_final (&json);
197 }
198 
199 // UgBufferFunc
buffer_to_file(UgBuffer * buffer)200 static int  buffer_to_file (UgBuffer* buffer)
201 {
202 	FILE*   file = buffer->data;
203 
204 	printf ("write %d bytes to file\n", ug_buffer_length (buffer));
205 	fwrite (buffer->beg, 1, ug_buffer_length(buffer), file);
206 	buffer->cur = buffer->beg;
207 	return 0;
208 }
209 
write_node_to_file(UgetNode * node,char * filename)210 void write_node_to_file (UgetNode* node, char* filename)
211 {
212 	UgBuffer  buffer;
213 	UgJson    json;
214 	FILE*     file;
215 
216 	file = fopen (filename, "w");
217 	ug_buffer_init (&buffer, 128);
218 	buffer.more = buffer_to_file;
219 	buffer.data = file;
220 
221 	ug_json_init (&json);
222 	ug_json_begin_write (&json, UG_JSON_FORMAT_INDENT, &buffer);
223 #if 1
224 	// method 1: use UgEntry to write start of object
225 	ug_json_write_entry (&json, node, NodeChildrenEntry);
226 #else
227 	// method 2: call ug_json_write_object_head() to write start of object
228 	ug_json_write_array_head (&json);
229 	ug_json_write_uget_node_children (&json, node);
230 	ug_json_write_array_tail (&json);
231 #endif
232 	ug_json_end_write (&json);
233 	ug_json_final (&json);
234 
235 	ug_buffer_clear (&buffer, 1);
236 	fclose (file);
237 }
238 
test_uget_node()239 void test_uget_node ()
240 {
241 	UgetNode* root;
242 
243 	root = uget_node_new (NULL);
244 #if 0
245 	init_node (root);
246 #else
247 	parse_node (root);
248 #endif
249 	write_node_to_file (root, "test-UgetNode.json");
250 }
251 
252 // ----------------------------------------------------------------------------
253 // UgetA2cf
254 
print_bitfield(uint8_t * bytes,int length)255 void print_bitfield (uint8_t* bytes, int length)
256 {
257 	int  count;
258 	int  index;
259 	int  temp;
260 
261 	for (index = 0;  index < length;  index++) {
262 		for (count = 0;  count < 8;  count++) {
263 			temp = (bytes[0] << count) & 0x80;
264 			if (temp)
265 				printf ("1");
266 			else
267 				printf ("0");
268 		}
269 		printf ("\n");
270 		bytes++;
271 	}
272 }
273 
print_a2cf(UgetA2cf * a2cf)274 void print_a2cf (UgetA2cf* a2cf)
275 {
276 	UgetA2cfPiece* piece;
277 
278 	if (a2cf == NULL)
279 		return;
280 
281 	printf ("ver : %d\n", (int)a2cf->ver);
282 	printf ("ext : %d\n", (int)a2cf->ext);
283 	printf ("info_hash_len : %d\n", (int)a2cf->info_hash_len);
284 
285 	printf ("piece_len : %d\n", (int)a2cf->piece_len);
286 	printf ("total_len : %d\n", (int)a2cf->total_len);
287 	printf ("upload_len : %d\n", (int)a2cf->upload_len);
288 
289 	printf ("bitfield_len : %d\n", (int)a2cf->bitfield_len);
290 	if (a2cf->bitfield_len) {
291 		printf ("bitfield:\n");
292 		print_bitfield (a2cf->bitfield, a2cf->bitfield_len);
293 	}
294 
295 	printf ("n_pieces : %d\n", (int)a2cf->piece.list.size);
296 	for (piece = (void*)a2cf->piece.list.head;  piece;  piece = piece->next) {
297 		printf ("index : %d\n", (int)piece->index);
298 		printf ("length : %d\n", (int)piece->length);
299 		printf ("bitfield_length : %d\n", (int)piece->bitfield_len);
300 		printf ("bitfield:\n");
301 		print_bitfield (piece->bitfield, piece->bitfield_len);
302 	}
303 }
304 
test_uget_a2cf(void)305 void test_uget_a2cf (void)
306 {
307 	UgetA2cf     a2cf;
308 	const char*  fname;
309 	uint64_t  beg, end;
310 
311 	memset (&a2cf, 0, sizeof (UgetA2cf));
312 	fname = "D:\\Downloads\\TestData-Aria2\\npp.6.4.2.Installer.exe.aria2-1";
313 	printf ("%s\n", fname);
314 	uget_a2cf_load (&a2cf, fname);
315 	print_a2cf (&a2cf);
316 	uget_a2cf_clear (&a2cf);
317 
318 	fname = "D:\\Downloads\\TestData-Aria2\\npp.6.4.2.Installer.exe.aria2-2";
319 	printf ("%s\n", fname);
320 	uget_a2cf_load (&a2cf, fname);
321 	// fill
322 	beg = 3145728 + 16384 * 2;
323 	end = 5242880 + 16384 * 4 + 1;
324 //	beg = 7340032; // + 16384 * 2;
325 //	end = 7401344;
326 	printf ("fill %d - %d\n", (int)beg, (int)end);
327 	printf ("fill result %d\n", (int)uget_a2cf_fill (&a2cf, beg, end));
328 	// lack
329 	beg = 0;
330 //	beg = 3145728 - 16384 * 2;
331 //	beg = 5242880;
332 //	beg = 7340032;
333 //	beg = 7401344;
334 	if (uget_a2cf_lack (&a2cf, &beg, &end))
335 		printf ("lack %d - %d\n", (int)beg, (int)end);
336 	print_a2cf (&a2cf);
337 	// completed
338 	printf ("completed: %u\n", (unsigned)uget_a2cf_completed (&a2cf));
339 	// clear
340 	uget_a2cf_clear (&a2cf);
341 
342 	fname = "D:\\Downloads\\TestData-Aria2\\npp.6.4.3.Installer.exe.aria2";
343 	printf ("%s\n", fname);
344 	uget_a2cf_load (&a2cf, fname);
345 	print_a2cf (&a2cf);
346 	// lack
347 	beg = 0;
348 	uget_a2cf_lack (&a2cf, &beg, &end);
349 	printf ("lack %d - %d\n", (int)beg, (int)end);
350 	uget_a2cf_clear (&a2cf);
351 
352 	fname = "D:\\Downloads\\TestData-Aria2\\ubuntu-13.04-desktop-amd64.iso.aria2";
353 	printf ("%s\n", fname);
354 	uget_a2cf_load (&a2cf, fname);
355 	print_a2cf (&a2cf);
356 	uget_a2cf_clear (&a2cf);
357 
358 	fname = "D:\\Downloads\\TestData-Aria2\\eclipse-cpp-kepler-R-win32.zip.aria2";
359 	printf ("%s\n", fname);
360 	uget_a2cf_load (&a2cf, fname);
361 	print_a2cf (&a2cf);
362 	uget_a2cf_clear (&a2cf);
363 }
364 
365 // ----------------------------------------------------------------------------
366 // UgetCurl
367 
test_uget_curl(void)368 void test_uget_curl (void)
369 {
370 	UgetCurl*  ugcurl;
371 
372 	ugcurl = uget_curl_new ();
373 	uget_curl_set_url (ugcurl, "http://msysgit.googlecode.com/files/Git-1.8.5.2-preview20131230.exe");
374 	uget_curl_open_file (ugcurl, NULL);
375 	ugcurl->header_store = TRUE;
376 	uget_curl_run (ugcurl, TRUE);
377 	ug_thread_join (&ugcurl->thread);
378 	uget_curl_free (ugcurl);
379 }
380 
381 // ----------------------------------------------------------------------------
382 // UgetRss
383 
test_uget_rss(void)384 void test_uget_rss (void)
385 {
386 	UgetRss*     urss;
387 	UgetRssFeed* feed;
388 	UgetRssItem* item = NULL;
389 
390 	urss = uget_rss_new ();
391 	uget_rss_add_builtin (urss, UGET_RSS_STABLE);
392 	uget_rss_update (urss, TRUE);
393 	ug_thread_join (&urss->thread);
394 
395 	feed = uget_rss_find_updated (urss, NULL);
396 	if (feed)
397 		item = uget_rss_feed_find (feed, -1);
398 	if (item)
399 		printf ("title %s\n", item->title);
400 
401 	uget_rss_unref (urss);
402 }
403 
404 // ----------------------------------------------------------------------------
405 // UgetMedia
406 
test_media(void)407 void  test_media (void)
408 {
409 	UgetMedia*     umedia;
410 	UgetMediaItem* umitem;
411 	int   count;
412 	char* uri;
413 
414 	uri = "https://www.youtube.com/watch?v=y2004Xaz2HU";
415 	count = uget_site_get_id (uri);
416 	umedia = uget_media_new (uri, UGET_SITE_YOUTUBE);
417 	count  = uget_media_grab_items (umedia, NULL);
418 	printf ("\nget %d media item\n", count);
419 
420 	umitem = uget_media_match (umedia,
421 			UGET_MEDIA_MATCH_1,
422 			UGET_MEDIA_QUALITY_UNKNOWN,
423 			UGET_MEDIA_TYPE_MP4);
424 
425 //	umitem = uget_media_match (umedia,
426 //			UGET_MEDIA_MATCH_0,
427 //			UGET_MEDIA_QUALITY_UNKNOWN,
428 //			UGET_MEDIA_TYPE_MP4);
429 
430 	for (;  umitem;  umitem = umitem->next) {
431 //		printf ("URL %s" "\n", umitem->url);
432 		printf ("quality %d, type %d, has_url %d\n",
433 		        umitem->quality, umitem->type,
434 		        (umitem->url) ? 1 : 0);
435 	}
436 	uget_media_free (umedia);
437 }
438 
439 // ----------------------------------------------------------------------------
440 // UgetSeq
441 
test_seq(void)442 void test_seq (void)
443 {
444 	UgetSequence  useq;
445 	UgList  list;
446 	UgLink* link;
447 
448 	ug_list_init (&list);
449 
450 	uget_sequence_init (&useq);
451 
452 	// digits
453 	uget_sequence_add (&useq, 0, 5, 2);
454 	// ASCII or Unicode
455 	uget_sequence_add (&useq, 'a', 'b', 0);
456 	uget_sequence_add (&useq, 0x7532, 0x7535, 0);
457 
458 	printf (" --- sequence ---  count = %d\n",
459 			uget_sequence_count (&useq, "http://sample/*-*-*.mp4"));
460 	uget_sequence_get_list (&useq, "http://sample/*-*-*.mp4", &list);
461 	for (link = list.head;  link;  link = link->next)
462 		puts (link->data);
463 	ug_list_foreach_link (&list, (UgForeachFunc)ug_free, NULL);
464 	ug_list_clear (&list, FALSE);
465 
466 	puts (" --- preview ---");
467 	uget_sequence_get_preview (&useq, "http://sample/*-*.mp4", &list);
468 	for (link = list.head;  link;  link = link->next)
469 		puts (link->data);
470 	ug_list_foreach_link (&list, (UgForeachFunc)ug_free, NULL);
471 	ug_list_clear (&list, FALSE);
472 
473 	uget_sequence_final (&useq);
474 }
475 
476 // ----------------------------------------------------------------------------
477 // UgetFiles
478 
test_files_json(UgetFiles * files)479 void test_files_json(UgetFiles* files)
480 {
481 	UgJson       json;
482 	UgBuffer     buffer;
483 	UgJsonError  code;
484 	UgetFiles*   files2;
485 
486 	ug_json_init(&json);
487 	ug_buffer_init(&buffer, 4096);
488 
489 	// write
490 	ug_json_begin_write(&json, UG_JSON_FORMAT_INDENT, &buffer);
491 	ug_json_write_object_head(&json);
492     ug_json_write_entry(&json, files, files->info->entry);
493 	ug_json_write_object_tail(&json);
494 	ug_json_end_write(&json);
495 	ug_buffer_write_char(&buffer, '\0');
496 	puts("\n--- print files ---");
497 	puts(buffer.beg);
498 
499 	files2 = ug_group_data_new(UgetFilesInfo);
500 	// parse
501 	ug_json_begin_parse(&json);
502 	ug_json_push(&json, ug_json_parse_entry, files2, (void*)files2->info->entry);
503 	ug_json_push(&json, ug_json_parse_object, NULL, NULL);
504 	code = ug_json_parse(&json, buffer.beg, -1);
505 	ug_json_end_parse(&json);
506 	printf("\n" "parse return %d\n", code);
507 
508 	// write
509 	buffer.cur = buffer.beg;
510 	ug_json_begin_write(&json, UG_JSON_FORMAT_INDENT, &buffer);
511     ug_json_write_entry(&json, files2, files2->info->entry);
512 	ug_json_end_write(&json);
513 	ug_buffer_write_char(&buffer, '\0');
514 	puts("\n--- print files2 ---");
515 	puts(buffer.beg);
516 
517 	ug_group_data_free(files2);
518 
519 	ug_buffer_clear(&buffer, TRUE);
520 	ug_json_final(&json);
521 }
522 
test_files(void)523 void test_files(void)
524 {
525 	UgetFiles* files;
526 	UgetFiles* src;
527 	UgetFile*  element;
528 
529 	files = ug_group_data_new(UgetFilesInfo);
530 	src   = ug_group_data_new(UgetFilesInfo);
531 
532 	element = uget_files_realloc(files, "0.mp4");
533 	element = uget_files_realloc(files, "1.mp4");
534 	element = uget_files_realloc(files, "2.mp4");
535 
536 	test_files_json(files);
537 
538 	element = uget_files_realloc(src, "0.mp4");
539 	element = uget_files_realloc(src, "1.mp4");
540 	element = uget_files_realloc(src, "2.mp4");
541 	element = uget_files_realloc(src, "3.mp4");
542 
543 	element = uget_files_realloc(src, "foo.mp4");
544 	element = uget_files_realloc(src, "xxx.apk");
545 
546 	uget_files_sync(files, src);
547 	test_files_json(files);
548 
549 	element->state |= UGET_FILE_STATE_DELETED;
550 	src->sync_count++;
551 
552 	uget_files_sync(files, src);
553 	test_files_json(files);
554 
555 	ug_group_data_free(files);
556 	ug_group_data_free(src);
557 }
558 
559 // ----------------------------------------------------------------------------
560 // main
561 
main(void)562 int main (void)
563 {
564 //	test_uget_node ();
565 //	test_fake_path ();
566 
567 //	test_uget_a2cf ();
568 //	test_uget_curl ();
569 //	test_uget_rss ();
570 //	test_media ();
571 //	test_seq ();
572 	test_files();
573 
574 	return 0;
575 }
576 
577