1 /* -*- Mode: c; c-basic-offset: 2 -*-
2 *
3 * note.c - Flickcurl note functions
4 *
5 * Copyright (C) 2010, David Beckett http://www.dajobe.org/
6 *
7 * This file is licensed under the following three licenses as alternatives:
8 * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version
9 * 2. GNU General Public License (GPL) V2 or any newer version
10 * 3. Apache License, V2.0 or any newer version
11 *
12 * You may not use this file except in compliance with at least one of
13 * the above three licenses.
14 *
15 * See LICENSE.html or LICENSE.txt at the top of this package for the
16 * complete terms and further detail along with the license texts for
17 * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively.
18 *
19 */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdarg.h>
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28
29 #ifdef WIN32
30 #include <win32_flickcurl_config.h>
31 #endif
32
33 #include <flickcurl.h>
34 #include <flickcurl_internal.h>
35
36
37 /**
38 * flickcurl_free_note:
39 * @note: note object
40 *
41 * Destructor for note object
42 */
43 void
flickcurl_free_note(flickcurl_note * note)44 flickcurl_free_note(flickcurl_note *note)
45 {
46 FLICKCURL_ASSERT_OBJECT_POINTER_RETURN(note, flickcurl_note);
47
48 if(note->author)
49 free(note->author);
50 if(note->authorname)
51 free(note->authorname);
52 if(note->text)
53 free(note->text);
54 free(note);
55 }
56
57
58 flickcurl_note**
flickcurl_build_notes(flickcurl * fc,flickcurl_photo * photo,xmlXPathContextPtr xpathCtx,const xmlChar * xpathExpr,int * note_count_p)59 flickcurl_build_notes(flickcurl* fc, flickcurl_photo* photo,
60 xmlXPathContextPtr xpathCtx, const xmlChar* xpathExpr,
61 int* note_count_p)
62 {
63 flickcurl_note** notes = NULL;
64 int nodes_count;
65 int note_count;
66 int i;
67 xmlXPathObjectPtr xpathObj = NULL;
68 xmlNodeSetPtr nodes;
69
70 /* Now do notes */
71 xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
72 if(!xpathObj) {
73 flickcurl_error(fc, "Unable to evaluate XPath expression \"%s\"",
74 xpathExpr);
75 fc->failed = 1;
76 goto tidy;
77 }
78
79 nodes = xpathObj->nodesetval;
80 /* This is a max size - it can include nodes that are CDATA */
81 nodes_count = xmlXPathNodeSetGetLength(nodes);
82 notes = (flickcurl_note**)calloc(sizeof(flickcurl_note*), nodes_count+1);
83
84 for(i = 0, note_count = 0; i < nodes_count; i++) {
85 xmlNodePtr node = nodes->nodeTab[i];
86 xmlAttr* attr;
87 flickcurl_note* n;
88 xmlNodePtr chnode;
89
90 if(node->type != XML_ELEMENT_NODE) {
91 flickcurl_error(fc, "Got unexpected node type %d", node->type);
92 fc->failed = 1;
93 break;
94 }
95
96 n = (flickcurl_note*)calloc(sizeof(flickcurl_note), 1);
97
98 for(attr = node->properties; attr; attr = attr->next) {
99 size_t attr_len = strlen((const char*)attr->children->content);
100 const char *attr_name = (const char*)attr->name;
101 char *attr_value;
102
103 attr_value = (char*)malloc(attr_len + 1);
104 memcpy(attr_value, attr->children->content, attr_len + 1);
105
106 if(!strcmp(attr_name, "id")) {
107 n->id = atoi(attr_value);
108 free(attr_value);
109 } else if(!strcmp(attr_name, "author"))
110 n->author = attr_value;
111 else if(!strcmp(attr_name, "authorname"))
112 n->authorname = attr_value;
113 else if(!strcmp(attr_name, "x")) {
114 n->x = atoi(attr_value);
115 free(attr_value);
116 } else if(!strcmp(attr_name, "y")) {
117 n->y = atoi(attr_value);
118 free(attr_value);
119 } else if(!strcmp(attr_name, "w")) {
120 n->w = atoi(attr_value);
121 free(attr_value);
122 } else if(!strcmp(attr_name, "h")) {
123 n->h = atoi(attr_value);
124 free(attr_value);
125 } else
126 free(attr_value);
127 }
128
129 /* Walk children nodes for text */
130 for(chnode = node->children; chnode; chnode = chnode->next) {
131 if(chnode->type == XML_TEXT_NODE) {
132 size_t len = strlen((const char*)chnode->content);
133 n->text = (char*)malloc(len + 1);
134 memcpy(n->text, chnode->content, len + 1);
135 }
136 }
137
138 #if FLICKCURL_DEBUG > 1
139 fprintf(stderr, "note: id %d author ID %s name %s x %d y %d w %d h %d text '%s'\n",
140 n->id, n->author, n->authorname, n->x, n->y, n->w, n->h, n->text);
141 #endif
142
143 notes[note_count++] = n;
144 } /* for nodes */
145
146 if(note_count_p)
147 *note_count_p = note_count;
148
149 tidy:
150 if(xpathObj)
151 xmlXPathFreeObject(xpathObj);
152
153 return notes;
154 }
155