102 destroy_db(db); |
104 destroy_db(db); |
103 return NULL; |
105 return NULL; |
104 } else { |
106 } else { |
105 return db; |
107 return db; |
106 } |
108 } |
|
109 } |
|
110 |
|
111 void process_parts(xmlTextReaderPtr reader, LocalResource *res) { |
|
112 UcxList *parts = NULL; |
|
113 |
|
114 FilePart *current_part = NULL; |
|
115 |
|
116 size_t count = 0; |
|
117 int field = -1; |
|
118 int err = 0; |
|
119 while(xmlTextReaderRead(reader)) { |
|
120 int type = xmlTextReaderNodeType(reader); |
|
121 const xmlChar *name = xmlTextReaderConstName(reader); |
|
122 int depth = xmlTextReaderDepth(reader); |
|
123 |
|
124 int part = TRUE; |
|
125 if(type == XML_READER_TYPE_ELEMENT) { |
|
126 if(depth == 3 && xstreq(name, "part")) { |
|
127 current_part = calloc(1, sizeof(FilePart)); |
|
128 current_part->block = count; |
|
129 parts = ucx_list_append(parts, current_part); |
|
130 count++; |
|
131 } else if(depth == 4) { |
|
132 if(xstreq(name, "hash")) { |
|
133 field = 0; |
|
134 } else if(xstreq(name, "etag")) { |
|
135 field = 1; |
|
136 } |
|
137 } |
|
138 } else if(type == XML_READER_TYPE_END_ELEMENT) { |
|
139 if(depth == 2) { |
|
140 // </parts> |
|
141 break; |
|
142 } else if(depth == 3) { |
|
143 if(current_part) { |
|
144 if(!current_part->hash || !current_part->etag) { |
|
145 err = 1; |
|
146 } |
|
147 } |
|
148 // </part> |
|
149 current_part = NULL; |
|
150 } |
|
151 field = -1; |
|
152 } else if(type == XML_READER_TYPE_TEXT && depth == 5 && current_part) { |
|
153 const char *text = (const char*)xmlTextReaderConstValue(reader); |
|
154 if(field == 0) { |
|
155 current_part->hash = strdup(text); |
|
156 } else if(field = 1) { |
|
157 current_part->etag = strdup(text); |
|
158 } |
|
159 } |
|
160 } |
|
161 |
|
162 if(err) { |
|
163 ucx_list_free_content(parts, (ucx_destructor)filepart_free); |
|
164 ucx_list_free(parts); |
|
165 return; |
|
166 } |
|
167 |
|
168 FilePart *file_parts = calloc(count, sizeof(FilePart)); |
|
169 size_t i = 0; |
|
170 UCX_FOREACH(elm, parts) { |
|
171 FilePart *p = elm->data; |
|
172 file_parts[i] = *p; |
|
173 free(p); |
|
174 i++; |
|
175 } |
|
176 |
|
177 ucx_list_free(parts); |
|
178 |
|
179 res->parts = file_parts; |
|
180 res->numparts = count; |
107 } |
181 } |
108 |
182 |
109 LocalResource* process_resource(xmlTextReaderPtr reader) { |
183 LocalResource* process_resource(xmlTextReaderPtr reader) { |
110 LocalResource *res = calloc(1, sizeof(LocalResource)); |
184 LocalResource *res = calloc(1, sizeof(LocalResource)); |
111 |
185 |
139 field = 10; |
213 field = 10; |
140 } else if(xstreq(name, "skipped")) { |
214 } else if(xstreq(name, "skipped")) { |
141 res->skipped = TRUE; |
215 res->skipped = TRUE; |
142 } else if(xstreq(name, "tags-updated")) { |
216 } else if(xstreq(name, "tags-updated")) { |
143 res->tags_updated = TRUE; |
217 res->tags_updated = TRUE; |
|
218 } else if(xstreq(name, "parts")) { |
|
219 process_parts(reader, res); |
144 } |
220 } |
145 } else if(type == XML_READER_TYPE_TEXT) { |
221 } else if(type == XML_READER_TYPE_TEXT) { |
146 const xmlChar *value = xmlTextReaderConstValue(reader); |
222 const xmlChar *value = xmlTextReaderConstValue(reader); |
147 //int b = 0; |
223 //int b = 0; |
148 switch(field) { |
224 switch(field) { |
439 xmlFreeTextWriter(writer); |
515 xmlFreeTextWriter(writer); |
440 return -1; |
516 return -1; |
441 } |
517 } |
442 } |
518 } |
443 |
519 |
|
520 if(res->numparts > 0) { |
|
521 r = xmlTextWriterStartElement(writer, BAD_CAST "parts"); |
|
522 if(r < 0) { |
|
523 xmlFreeTextWriter(writer); |
|
524 return -1; |
|
525 } |
|
526 for(size_t i=0;i<res->numparts;i++) { |
|
527 FilePart p = res->parts[i]; |
|
528 r = xmlTextWriterStartElement(writer, BAD_CAST "part"); |
|
529 if(r < 0) { |
|
530 xmlFreeTextWriter(writer); |
|
531 return -1; |
|
532 } |
|
533 |
|
534 if(p.hash) { |
|
535 r = xmlTextWriterWriteElement(writer, BAD_CAST "hash", BAD_CAST p.hash); |
|
536 if(r < 0) { |
|
537 xmlFreeTextWriter(writer); |
|
538 return -1; |
|
539 } |
|
540 } |
|
541 if(p.etag) { |
|
542 r = xmlTextWriterWriteElement(writer, BAD_CAST "etag", BAD_CAST p.etag); |
|
543 if(r < 0) { |
|
544 xmlFreeTextWriter(writer); |
|
545 return -1; |
|
546 } |
|
547 } |
|
548 r = xmlTextWriterEndElement(writer); |
|
549 if(r < 0) { |
|
550 xmlFreeTextWriter(writer); |
|
551 return -1; |
|
552 } |
|
553 } |
|
554 r = xmlTextWriterEndElement(writer); |
|
555 if(r < 0) { |
|
556 xmlFreeTextWriter(writer); |
|
557 return -1; |
|
558 } |
|
559 } |
|
560 |
444 // </resource> |
561 // </resource> |
445 xmlTextWriterEndElement(writer); |
562 xmlTextWriterEndElement(writer); |
446 } |
563 } |
447 |
564 |
448 // write all remove entries |
565 // write all remove entries |