1 /*
2 * XmlUtil.c
3 *
4 * Created on: Jul 28, 2008
5 * Author: mr@marcelruff.info
6 */
7 #include <stdio.h> /* fseek etc */
8 #include <string.h>
9 #include <stdlib.h>
10 #include <util/helper.h>
11 #include <util/msgUtil.h>
12 #include "XmlUtil.h"
13
14 static const char * const AMP = "&";
15 static const char * const LT = "<";
16 static const char * const GT = ">";
17 static const char * const QUOT = """;
18 static const char * const APOS = "'";
19
20 static const char * const SLASH_R = "
";
21 static const char * const NULL_ = "�";
22
23 static const char * const COMMA = ",";
24
25
26 /**
27 * <p k="Hello">
28 * @param attributeValue if not 0 it must match as well
29 * @param start out parameter for pos of 'H', -1 if not found
30 * @param end out parameter for pos of '"' after 'o'
31 *
32 */
33 static void xmlBlasterExtractAttributePos(const char * const xml,
34 const char * const tag, const char * const attributeName,
35 const char * const attributeValue, int *start, int *end) {
36 *start = -1;
37 *end = -1;
38 if (xml == 0 || tag == 0 || attributeName == 0)
39 return;
40 {
41 bool insideTag = false;
42 int i;
43 int len = (int)strlen(xml);
44 char *startTag = strcpyAlloc("<");
45 char *attrToken = strcpyAlloc(attributeName);
46 startTag = strcatAlloc(&startTag, tag);
47 attrToken = strcatAlloc(&attrToken, "=");
48 for (i = 0; i < len; i++) {
49 if (xml[i] == '>') {
50 insideTag = false;
51 continue;
52 }
53 if (insideTag) {
54 if (startsWith(xml + i, attrToken)) {
55 int pos = i + (int)strlen(attrToken);
56 char apos = xml[pos];
57 int curr = 0;
58 *start = pos + 1;
59 i = pos + 1;
60 for (; i < len; i++, curr++) {
61 if (xml[i] == apos) {
62 *end = i;
63 xmlBlasterFree(startTag);
64 xmlBlasterFree(attrToken);
65 return;
66 }
67 if (attributeValue != 0) {
68 if (xml[i] != attributeValue[curr]) {
69 insideTag = false;
70 break;
71 }
72 }
73 }
74 }
75 continue;
76 }
77 if (startsWith(xml + i, startTag)) {
78 insideTag = true;
79 continue;
80 }
81 }
82 xmlBlasterFree(startTag);
83 xmlBlasterFree(attrToken);
84 *start = -1;
85 }
86 }
87
88 Dll_Export char *xmlBlasterExtractAttributeValue(const char * const xml,
89 const char * const tag, const char * const attributeName) {
90 if (xml == 0 || tag == 0 || attributeName == 0)
91 return 0;
92 {
93 int start, end;
94 xmlBlasterExtractAttributePos(xml, tag, attributeName, 0, &start, &end);
95 if (start >= 0) {
96 int count = end - start;
97 char *ret = (char *) malloc((count + 1) * sizeof(char));
98 int j;
99 ret[count] = 0;
100 for (j = 0; j < count; j++) {
101 ret[j] = xml[start + j];
102 }
103 return ret;
104 }
105 }
106 return 0;
107 }
108
109 Dll_Export long xmlBlasterExtractAttributeLong(const char * const xml,
110 const char * const tag, const char * const attributeName, long defaultValue) {
111 long val = defaultValue;
112 char *valP = xmlBlasterExtractAttributeValue(xml, tag, attributeName);
113 if (valP == 0)
114 return defaultValue;
115 # if _MSC_VER >= 1400 && !defined(WINCE)
116 if (sscanf_s(valP, "%ld", &val) == 1)
117 # else
118 if (sscanf(valP, "%ld", &val) == 1)
119 # endif
120 return val;
121 return defaultValue;
122 }
123
124 Dll_Export char *xmlBlasterExtractTagValueWithAttribute(const char * const xml,
125 const char * const tag, const char * const attributeName,
126 const char * const attributeValue) {
127 if (xml == 0 || tag == 0 || attributeName == 0)
128 return 0;
129 {
130 int startAttr, endAttr;
131 xmlBlasterExtractAttributePos(xml, tag, attributeName, attributeValue,
132 &startAttr, &endAttr);
133 if (startAttr >= 0) {
134 int i;
135 int len = (int)strlen(xml);
136 for (i = endAttr; i < len; i++) {
137 if (xml[i] == '>') {
138 if (i == len - 1)
139 return strcpyAlloc("");
140 {
141 const char *p = strstr(xml + i, "<");
142 int startVal = i + 1;
143 int endTag = (p == 0) ? len : len - (int)strlen(p);
144 int count = endTag - startVal;
145 char *ret = (char *) malloc((count + 1) * sizeof(char));
146 int j;
147 ret[count] = '\0';
148 for (j = 0; j < count; j++) {
149 ret[j] = xml[startVal + j];
150 }
151 return ret;
152 }
153 }
154 }
155 }
156 return 0;
157 }
158 }
159
160 Dll_Export char *xmlBlasterExtractTagValue(const char * const xml,
161 const char * const tag) {
162 if (xml == 0 || tag == 0)
163 return 0;
164 {
165 const char *startP = 0;
166 char *tagP = strcpyAlloc("<");
167 strcatAlloc(&tagP, tag);
168 startP = strstr(xml, tagP);
169 if (startP != 0) {
170 int i;
171 int start = -1, end = -1;
172 int len = (int)strlen(startP);
173 for (i = 1; i < len; i++) {
174 if (startP[i] == '>') {
175 start = i+1;
176 }
177 else if (startP[i] == '<') {
178 end = i;
179 break;
180 }
181 }
182 if (start >= 0 && end >= start) {
183 int j = 0;
184 int newLen = 0;
185 char *ret = (char *)malloc((end-start+1)*sizeof(char));
186 for (i = start; i < end; i++, j++) {
187 ret[j] = startP[i];
188 }
189 ret[end-start] = 0;
190 xmlBlasterFree(tagP);
191 return xmlBlasterUnEscapeXml(ret, &newLen);
192 }
193 }
194 xmlBlasterFree(tagP);
195 return 0;
196 }
197 }
198
199 Dll_Export char* xmlBlasterEscapeXml(const char *xml) {
200 if (xml == 0)
201 return strcpyAlloc("");
202 return xmlBlasterEscapeXmlBytes((int)strlen(xml), xml);
203 }
204
205 Dll_Export char* xmlBlasterEscapeXmlBytes(int len, const char *bytes) {
206 int i, newLen, pos;
207 char *res;
208 if (bytes == 0 || *bytes == 0 || len < 1)
209 return strcpyAlloc("");
210 newLen = len + 100;
211 res = (char *) malloc(newLen * sizeof(char));
212 memset(res, 0, newLen * sizeof(char));
213 pos = 0; /* new index */
214 for (i = 0; i < len; i++, pos++) {
215 /* Guarantee more space of at least strlen(,) */
216 if (pos >= (newLen-10)) {
217 newLen += (len < 1000) ? 100 : len/10;
218 res = (char *)realloc(res, newLen * sizeof(char));
219 memset(res+pos, '\0', (size_t)(newLen-pos));
220 }
221 if (bytes[i] == '&') {
222 strcat(res + pos, AMP);
223 pos += (int)strlen(AMP)-1;
224 } else if (bytes[i] == '<') {
225 strcat(res + pos, LT);
226 pos += (int)strlen(LT)-1;
227 } else if (bytes[i] == '>') {
228 strcat(res + pos, GT);
229 pos += (int)strlen(GT)-1;
230 } else if (bytes[i] == '"') {
231 strcat(res + pos, QUOT);
232 pos += (int)strlen(QUOT)-1;
233 } else if (bytes[i] == '\'') {
234 strcat(res + pos, APOS);
235 pos += (int)strlen(APOS)-1;
236 } else if (bytes[i] == '\r') {
237 strcat(res + pos, SLASH_R);
238 pos += (int)strlen(SLASH_R)-1;
239 } else if (bytes[i] == '\0') {
240 strcat(res + pos, NULL_);
241 pos += (int)strlen(NULL_)-1;
242 } else {
243 res[pos] = bytes[i];
244 }
245 }
246 *(res + pos) = 0;
247 return res;
248 }
249
250 Dll_Export char *xmlBlasterUnEscapeXml(char * const xml, int *newLen) {
251 int i, len, pos;
252 *newLen = 0;
253 if (xml == 0)
254 return xml;
255 len = (int)strlen(xml);
256 pos = 0; /* new index */
257 for (i = 0; i < len; i++, pos++) {
258 if (xml[i] != '&') {
259 xml[pos] = xml[i];
260 continue;
261 }
262 if (startsWith(xml + i, AMP)) {
263 xml[pos] = '&';
264 i += (int)strlen(AMP) - 1;
265 } else if (startsWith(xml + i, LT)) {
266 xml[pos] = '<';
267 i += (int)strlen(LT) - 1;
268 } else if (startsWith(xml + i, GT)) {
269 xml[pos] = '>';
270 i += (int)strlen(GT) - 1;
271 } else if (startsWith(xml + i, QUOT)) {
272 xml[pos] = '"';
273 i += (int)strlen(QUOT) - 1;
274 } else if (startsWith(xml + i, APOS)) {
275 xml[pos] = '\'';
276 i += (int)strlen(APOS) - 1;
277 } else if (startsWith(xml + i, SLASH_R)) {
278 xml[pos] = '\r';
279 i += (int)strlen(SLASH_R) - 1;
280 } else if (startsWith(xml + i, NULL_)) {
281 xml[pos] = '\0';
282 i += (int)strlen(NULL_) - 1;
283 }
284 }
285 *(xml + pos) = 0;
286 *newLen = pos;
287 return xml;
288 }
289
290 Dll_Export char* xmlBlasterEscapeCSV(const char *csv) {
291 int i, len, pos;
292 char *res;
293 if (csv == 0 || *csv == 0)
294 return strcpyAlloc("");
295 len = (int)strlen(csv);
296 res = (char *) malloc(5 * len * sizeof(char));
297 memset(res, 0, 5 * len * sizeof(char));
298 pos = 0; /* new index */
299 for (i = 0; i < len; i++, pos++) {
300 if (csv[i] == ',') {
301 strcat(res + pos, COMMA);
302 pos += (int)strlen(COMMA)-1;
303 } else {
304 res[pos] = csv[i];
305 }
306 }
307 *(res + pos) = 0;
308 return res;
309 }
310
311 Dll_Export char *xmlBlasterUnEscapeCSV(char * const csv, int *newLen) {
312 int i, len, pos;
313 *newLen = 0;
314 if (csv == 0)
315 return csv;
316 len = (int)strlen(csv);
317 pos = 0; /* new index */
318 for (i = 0; i < len; i++, pos++) {
319 if (csv[i] != '&') {
320 csv[pos] = csv[i];
321 continue;
322 }
323 if (startsWith(csv + i, COMMA)) {
324 csv[pos] = ',';
325 i += (int)strlen(COMMA) - 1;
326 }
327 }
328 *(csv + pos) = 0;
329 *newLen = pos;
330 return csv;
331 }
332
333 Dll_Export char *xmlBlasterReadBinaryFile(const char *name, int *len)
334 {
335 FILE *file;
336 char *buffer = 0;
337 unsigned long fileLen;
338
339 *len = 0;
340
341 file = fopen(name, "rb");
342 if (!file)
343 {
344 fprintf(stderr, "xmlBlasterReadBinaryFile: Unable to open file %s\n", name);
345 return 0;
346 }
347
348 /*Get file length*/
349 fseek(file, 0, SEEK_END);
350 fileLen=ftell(file);
351 fseek(file, 0, SEEK_SET);
352
353 buffer=(char *)malloc(fileLen+1);
354 if (!buffer)
355 {
356 fprintf(stderr, "xmlBlasterReadBinaryFile: Memory error!\n");
357 fclose(file);
358 return 0;
359 }
360
361 *len = (int)fread(buffer, 1, fileLen, file);
362 fclose(file);
363
364 return buffer;
365 }
syntax highlighted by Code2HTML, v. 0.9.1