1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
#include <stdbool.h>
#include <tidy.h>
#include <tidybuffio.h>
#include <icclient.h>
static void recurse_catalog(TidyDoc doc, TidyNode tnod, const char *image_dir,
struct icclient_catalog **catalog)
{
for (TidyNode child = tidyGetChild(tnod); child; child = tidyGetNext(child)) {
ctmbstr name = tidyNodeGetName(child);
if (!name)
continue;
if (strcmp(name, "img")) {
recurse_catalog(doc, child, image_dir, catalog);
continue;
}
static const char *subdir = "/thumb/";
char prefix[strlen(image_dir) + strlen(subdir) + 1];
size_t prefix_len = strlen(prefix);
bool bail = false;
for (TidyAttr attr = tidyAttrFirst(child); attr; attr = tidyAttrNext(attr))
if (!strcmp(tidyAttrName(attr), "src")
&& strncmp(tidyAttrValue(attr), prefix, prefix_len)) {
bail = true;
break;
}
if (bail)
continue;
struct icclient_product *product = malloc(sizeof(struct icclient_product));
memset(product, '\0', sizeof(struct icclient_product));
for (TidyAttr attr = tidyAttrFirst(child); attr; attr = tidyAttrNext(attr)) {
name = tidyAttrName(attr);
ctmbstr value = tidyAttrValue(attr);
if (!strcmp(name, "src")) {
size_t len = strlen(value) - prefix_len;
product->image = malloc(len + 1);
strncpy(product->image, value + prefix_len, len + 1);
} else if (!strcmp(name, "alt")) {
product->description = malloc(strlen(value) + 1);
strcpy(product->description, value);
} else if (!strcmp(name, "title")) {
product->sku = malloc(strlen(value + 1));
strcpy(product->sku, value);
}
}
(*catalog)->length++;
*catalog = realloc(*catalog, sizeof(struct icclient_catalog)
+ sizeof(struct icclient_product *[(*catalog)->length]));
(*catalog)->products[(*catalog)->length - 1] = product;
}
}
struct icclient_catalog *catalog(const char *response, const char *image_dir)
{
TidyDoc tdoc = tidyCreate();
TidyBuffer output = {0};
tidyParseString(tdoc, response);
tidySaveBuffer(tdoc, &output);
struct icclient_catalog *catalog = malloc(sizeof(struct icclient_catalog));
catalog->length = 0;
recurse_catalog(tdoc, tidyGetRoot(tdoc), image_dir, &catalog);
tidyBufFree(&output);
tidyRelease(tdoc);
return catalog;
}
|