00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <libsyncml/syncml.h>
00023
00024 #include <libsyncml/syncml_internals.h>
00025 #include <libsyncml/sml_elements_internals.h>
00026 #include <libsyncml/sml_command_internals.h>
00027 #include <libsyncml/sml_devinf_internals.h>
00028 #include <libsyncml/sml_session_internals.h>
00029 #include "libsyncml/sml_error_internals.h"
00030
00031 #include "sml_xml_parse.h"
00032 #include "sml_xml_parse_internals.h"
00033
00034 #define BUFFER_SIZE 500
00035
00036 static SmlBool _smlXmlParserStep(SmlXmlParser *parser)
00037 {
00038 SmlBool ret = FALSE;
00039 do {
00040 ret = (xmlTextReaderRead(parser->reader) == 1) ? TRUE : FALSE;
00041 } while (ret && (xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_DOCUMENT_TYPE || \
00042 xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_WHITESPACE || \
00043 xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_SIGNIFICANT_WHITESPACE));
00044
00045 return ret;
00046 }
00047
00048 static SmlBool _smlXmlParserStepData(SmlXmlParser *parser)
00049 {
00050 SmlBool ret = FALSE;
00051 do {
00052 ret = (xmlTextReaderRead(parser->reader) == 1) ? TRUE : FALSE;
00053 } while (ret && (xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_DOCUMENT_TYPE || \
00054 xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_WHITESPACE));
00055
00056 return ret;
00057 }
00058
00059 static SmlBool _smlXmlSkipNode(SmlXmlParser *parser)
00060 {
00061 int node_type;
00062
00063 if (xmlTextReaderNext(parser->reader) != 1)
00064 return FALSE;
00065
00066 node_type = xmlTextReaderNodeType(parser->reader);
00067 while (xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_DOCUMENT_TYPE ||
00068 xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_WHITESPACE ||
00069 xmlTextReaderNodeType(parser->reader) == XML_READER_TYPE_SIGNIFICANT_WHITESPACE)
00070 {
00071 if (!_smlXmlParserStep (parser))
00072 return FALSE;
00073 }
00074
00075 return TRUE;
00076 }
00077
00078 static SmlBool _smlXmlParserExpectNode(SmlXmlParser *parser, int type, SmlBool empty, const char *name, SmlError **error)
00079 {
00080 CHECK_ERROR_REF
00081 if (!_smlXmlParserStep(parser)) {
00082 smlErrorSet(error, SML_ERROR_GENERIC, "No node at all");
00083 return FALSE;
00084 }
00085
00086 if (xmlTextReaderNodeType(parser->reader) != type) {
00087 smlErrorSet(error, SML_ERROR_GENERIC, "wrong node type");
00088 return FALSE;
00089 }
00090
00091
00092 switch (type) {
00093 case XML_NODE_START:
00094 case XML_NODE_CLOSE:
00095 if (name) {
00096 if (!xmlTextReaderConstName(parser->reader)) {
00097 smlErrorSet(error, SML_ERROR_GENERIC, "no name");
00098 return FALSE;
00099 }
00100
00101 if (strcmp((char *)xmlTextReaderConstName(parser->reader), name)) {
00102 smlErrorSet(error, SML_ERROR_GENERIC, "Wrong name");
00103 return FALSE;
00104 }
00105 }
00106 break;
00107 case XML_NODE_TEXT:
00108 if (!empty && !xmlTextReaderConstName(parser->reader)) {
00109 smlErrorSet(error, SML_ERROR_GENERIC, "Empty.");
00110 return FALSE;
00111 }
00112 break;
00113 default:
00114 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown node type");
00115 return FALSE;
00116 }
00117
00118 return TRUE;
00119 }
00120
00121 static SmlBool _smlXmlParserGetID(SmlXmlParser *parser, unsigned int *id, const char *name, SmlError **error)
00122 {
00123 CHECK_ERROR_REF
00124 smlAssert(parser);
00125 smlAssert(id);
00126
00127 if (*id) {
00128 smlErrorSet(error, SML_ERROR_GENERIC, "Id already set");
00129 goto error;
00130 }
00131
00132 if (!_smlXmlParserExpectNode(parser, XML_NODE_TEXT, FALSE, NULL, error))
00133 goto error;
00134
00135 *id = atoi(g_strstrip((char *)xmlTextReaderConstValue(parser->reader)));
00136
00137 if (!_smlXmlParserExpectNode(parser, XML_NODE_CLOSE, FALSE, name, error))
00138 goto error;
00139
00140 return TRUE;
00141
00142 error:
00143 return FALSE;
00144 }
00145
00146 static SmlBool _smlXmlParserGetString(SmlXmlParser *parser, char **string, const char *name, SmlError **error)
00147 {
00148 CHECK_ERROR_REF
00149 smlAssert(parser);
00150 smlAssert(string);
00151
00152 if (*string) {
00153 smlErrorSet(error, SML_ERROR_GENERIC, "string already set");
00154 goto error;
00155 }
00156
00157
00158 if (xmlTextReaderIsEmptyElement(parser->reader)) {
00159 *string = g_strdup("");
00160 return TRUE;
00161 }
00162
00163 if (!_smlXmlParserStep(parser)) {
00164 smlErrorSet(error, SML_ERROR_GENERIC, "No node at all");
00165 goto error_clear;
00166 }
00167
00168 if (xmlTextReaderNodeType(parser->reader) == XML_NODE_TEXT) {
00169 *string = g_strstrip(g_strdup((char *)xmlTextReaderConstValue(parser->reader)));
00170
00171 if (!_smlXmlParserExpectNode(parser, XML_NODE_CLOSE, FALSE, name, error))
00172 goto error_clear;
00173 } else if (xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00174 *string = g_strdup("");
00175 } else {
00176 smlErrorSet(error, SML_ERROR_GENERIC, "wrong node type");
00177 goto error_clear;
00178 }
00179
00180 return TRUE;
00181
00182 error_clear:
00183 *string = NULL;
00184 error:
00185 return FALSE;
00186 }
00187
00188 static SmlBool _smlXmlParserGetData(SmlXmlParser *parser, char **string, unsigned int *size, const char *name, SmlError **error)
00189 {
00190 CHECK_ERROR_REF
00191 smlAssert(parser);
00192 smlAssert(string);
00193 int rc = 0;
00194
00195 if (*string) {
00196 smlErrorSet(error, SML_ERROR_GENERIC, "string already set");
00197 return FALSE;
00198 }
00199
00200
00201 xmlBuffer *buffer = xmlBufferCreateSize(BUFFER_SIZE);
00202 if (!buffer) {
00203 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to create new buffer");
00204 goto error;
00205 }
00206
00207 xmlTextWriter *writer = xmlNewTextWriterMemory(buffer, 0);
00208 if (!writer) {
00209 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to create new writer");
00210 goto error_free_buffer;
00211 }
00212
00213
00214 if (xmlTextReaderIsEmptyElement(parser->reader))
00215 goto out;
00216
00217 while (1) {
00218 if (!_smlXmlParserStepData(parser)) {
00219 smlErrorSet(error, SML_ERROR_GENERIC, "There is a missing node during the data parsing of %s.", name);
00220 goto error_free_writer;
00221 }
00222
00223 switch (xmlTextReaderNodeType(parser->reader)) {
00224 case XML_NODE_CLOSE:
00225 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), name))
00226 goto out;
00227
00228 if (!xmlTextReaderIsEmptyElement(parser->reader))
00229 rc = xmlTextWriterEndElement(writer);
00230
00231 if (rc < 0) {
00232 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to end node");
00233 goto error_free_writer;
00234 }
00235 break;
00236 case XML_NODE_START:
00237 if (!xmlTextReaderIsEmptyElement(parser->reader))
00238 rc = xmlTextWriterStartElementNS(writer, NULL, xmlTextReaderConstName(parser->reader), NULL);
00239 else
00240 rc = xmlTextWriterWriteElementNS(writer, NULL, xmlTextReaderConstName(parser->reader), NULL, (const xmlChar*)"");
00241
00242 if (rc < 0) {
00243 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to start node");
00244 goto error_free_writer;
00245 }
00246 break;
00247 case XML_NODE_CDATA:
00248 case XML_NODE_TEXT:
00249 rc = xmlTextWriterWriteRaw(writer, xmlTextReaderConstValue(parser->reader));
00250 if (rc < 0) {
00251 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to add string");
00252 goto error_free_writer;
00253 }
00254 break;
00255 case XML_READER_TYPE_SIGNIFICANT_WHITESPACE:
00256 rc = xmlTextWriterWriteRaw(writer, xmlTextReaderConstValue(parser->reader));
00257 if (rc < 0) {
00258 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to add string");
00259 goto error_free_writer;
00260 }
00261 break;
00262 default:
00263 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown node type");
00264 goto error_free_writer;
00265 }
00266 }
00267
00268 out:
00269
00270
00271
00272
00273
00274
00275
00276 xmlFreeTextWriter(writer);
00277 *string = g_strndup((const char *) xmlBufferContent(buffer), xmlBufferLength(buffer));
00278 if (size)
00279 *size = xmlBufferLength(buffer);
00280
00281 xmlBufferFree(buffer);
00282
00283 return TRUE;
00284
00285 error_free_writer:
00286 xmlFreeTextWriter(writer);
00287 error_free_buffer:
00288 xmlBufferFree(buffer);
00289 error:
00290 *string = NULL;
00291 if (size) *size = 0;
00292 return FALSE;
00293 }
00294
00295 static SmlBool _smlSyncHeaderParseDTD(SmlProtocolVersion *version, SmlXmlParser *parser, SmlError **error)
00296 {
00297 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, version, parser, error);
00298 CHECK_ERROR_REF
00299 smlAssert(parser);
00300 smlAssert(version);
00301
00302 if (*version) {
00303 smlErrorSet(error, SML_ERROR_GENERIC, "dtd already set");
00304 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00305 return FALSE;
00306 }
00307
00308 char *dtd = NULL;
00309 if (!_smlXmlParserGetString(parser, &dtd, SML_ELEMENT_VERDTD, error))
00310 goto error;
00311
00312 if (!strcmp(dtd, "1.0"))
00313 *version = SML_VERSION_10;
00314 else if (!strcmp(dtd, "1.1"))
00315 *version = SML_VERSION_11;
00316 else if (!strcmp(dtd, "1.2"))
00317 *version = SML_VERSION_12;
00318 else {
00319 smlSafeCFree(&dtd);
00320 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown VerDTD");
00321 goto error;
00322 }
00323 smlSafeCFree(&dtd);
00324
00325 smlTrace(TRACE_EXIT, "%s", __func__);
00326 return TRUE;
00327
00328 error:
00329 *version = SML_VERSION_UNKNOWN;
00330 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00331 return FALSE;
00332 }
00333
00334 static SmlBool _smlSyncHeaderParseProto(SmlProtocolType *type, SmlXmlParser *parser, SmlError **error)
00335 {
00336 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, type, parser, error);
00337 CHECK_ERROR_REF
00338 smlAssert(parser);
00339 smlAssert(type);
00340
00341 if (*type) {
00342 smlErrorSet(error, SML_ERROR_GENERIC, "protocol already set");
00343 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00344 return FALSE;
00345 }
00346
00347 char *proto = NULL;
00348 if (!_smlXmlParserGetString(parser, &proto, SML_ELEMENT_VERPROTO, error))
00349 goto error;
00350
00351 if (!strcmp(proto, SML_VERSION_STRING_10) || !strcmp(proto, SML_VERSION_STRING_11) || !strcmp(proto, SML_VERSION_STRING_12))
00352 *type = SML_PROTOCOL_SYNCML;
00353 else {
00354 smlSafeCFree(&proto);
00355 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown VerProto");
00356 goto error;
00357 }
00358 smlSafeCFree(&proto);
00359
00360 smlTrace(TRACE_EXIT, "%s", __func__);
00361 return TRUE;
00362
00363 error:
00364 *type = SML_PROTOCOL_UNKNOWN;
00365 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00366 return FALSE;
00367 }
00368
00369
00370 static SmlBool _smlLocationParse(SmlLocation **location, SmlXmlParser *parser, SmlError **error)
00371 {
00372 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, location, parser, error);
00373 CHECK_ERROR_REF
00374 smlAssert(parser);
00375 smlAssert(location);
00376
00377 if (*location) {
00378 smlErrorSet(error, SML_ERROR_GENERIC, "Location already set");
00379 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00380 return FALSE;
00381 }
00382
00383 *location = smlTryMalloc0(sizeof(SmlLocation), error);
00384 if (!location)
00385 goto error;
00386 (*location)->refCount = 1;
00387
00388 while (1) {
00389 if (!_smlXmlParserStep(parser)) {
00390 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
00391 goto error_free_location;
00392 }
00393
00394 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET) && \
00395 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00396 break;
00397 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE) && \
00398 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00399 break;
00400 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE_PARENT) && \
00401 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00402 break;
00403 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET_PARENT) && \
00404 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00405 break;
00406 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00407 smlErrorSet(error, SML_ERROR_GENERIC,
00408 "The element %s is not a start node in locations (Target, Source, SourceParent or TargetParent).",
00409 xmlTextReaderConstName(parser->reader));
00410 goto error_free_location;
00411 }
00412
00413 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_LOCURI)) {
00414 if (!_smlXmlParserGetString(parser, &((*location)->locURI), SML_ELEMENT_LOCURI, error))
00415 goto error_free_location;
00416 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_LOCNAME)) {
00417 if (!_smlXmlParserGetString(parser, &((*location)->locName), SML_ELEMENT_LOCNAME, error))
00418 goto error_free_location;
00419 } else {
00420 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node. expected SyncHdr");
00421 goto error_free_location;
00422 }
00423 }
00424
00425 if (!(*location)->locURI) {
00426 smlErrorSet(error, SML_ERROR_GENERIC, "No locURI set");
00427 goto error_free_location;
00428 }
00429
00430 smlTrace(TRACE_EXIT, "%s", __func__);
00431 return TRUE;
00432
00433 error_free_location:
00434 smlLocationUnref(*location);
00435 error:
00436 *location = NULL;
00437 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00438 return FALSE;
00439 }
00440
00441 static SmlBool _smlAnchorParse(SmlAnchor **anchor, SmlXmlParser *parser, SmlError **error)
00442 {
00443 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, anchor, parser, error);
00444 CHECK_ERROR_REF
00445 smlAssert(parser);
00446 smlAssert(anchor);
00447
00448 if (*anchor) {
00449 smlErrorSet(error, SML_ERROR_GENERIC, "anchor already set");
00450 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00451 return FALSE;
00452 }
00453
00454 *anchor = smlTryMalloc0(sizeof(SmlAnchor), error);
00455 if (!anchor)
00456 goto error;
00457
00458 while (1) {
00459 if (!_smlXmlParserStep(parser)) {
00460 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
00461 goto error_free_anchor;
00462 }
00463
00464 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ANCHOR) && \
00465 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00466 break;
00467 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00468 smlErrorSet(error, SML_ERROR_GENERIC,
00469 "The element %s is not a start node in Anchor.",
00470 xmlTextReaderConstName(parser->reader));
00471 goto error_free_anchor;
00472 }
00473
00474 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_NEXT)) {
00475 if (!_smlXmlParserGetString(parser, &((*anchor)->next), SML_ELEMENT_NEXT, error))
00476 goto error_free_anchor;
00477 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_LAST)) {
00478 if (!_smlXmlParserGetString(parser, &((*anchor)->last), SML_ELEMENT_LAST, error))
00479 goto error_free_anchor;
00480 } else {
00481 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
00482 goto error_free_anchor;
00483 }
00484 }
00485
00486 if (!(*anchor)->next) {
00487 smlErrorSet(error, SML_ERROR_GENERIC, "No next set");
00488 goto error_free_anchor;
00489 }
00490
00491 smlTrace(TRACE_EXIT, "%s", __func__);
00492 return TRUE;
00493
00494 error_free_anchor:
00495 smlAnchorFree(*anchor);
00496 error:
00497 *anchor = NULL;
00498 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00499 return FALSE;
00500 }
00501
00502 static SmlBool _smlChalMetaParse(SmlXmlParser *parser, char **format, char **type, char **nonce, SmlError **error)
00503 {
00504 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p, %p, %p)", __func__, parser, format, type, nonce, error);
00505 CHECK_ERROR_REF
00506 smlAssert(parser);
00507
00508 while (1) {
00509 if (!_smlXmlParserStep(parser)) {
00510 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
00511 goto error;
00512 }
00513
00514 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META) && \
00515 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00516 break;
00517 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00518 smlErrorSet(error, SML_ERROR_GENERIC,
00519 "The element %s is not a start node in Chal/Meta.",
00520 xmlTextReaderConstName(parser->reader));
00521 goto error;
00522 }
00523
00524 if (type && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TYPE)) {
00525 if (!_smlXmlParserGetString(parser, type, SML_ELEMENT_TYPE, error))
00526 goto error;
00527 } else if (format && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FORMAT)) {
00528 if (!_smlXmlParserGetString(parser, format, SML_ELEMENT_FORMAT, error))
00529 goto error;
00530 } else if (format && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_NEXTNONCE)) {
00531 if (!_smlXmlParserGetString(parser, nonce, SML_ELEMENT_NEXTNONCE, error))
00532 goto error;
00533 } else {
00534 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node: %s", xmlTextReaderConstName(parser->reader));
00535 goto error;
00536 }
00537 }
00538
00539 smlTrace(TRACE_EXIT, "%s", __func__);
00540 return TRUE;
00541
00542 error:
00543 if (format)
00544 *format = NULL;
00545 if (nonce)
00546 *nonce = NULL;
00547 if (type)
00548 *type = NULL;
00549
00550 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00551 return FALSE;
00552 }
00553
00554 static SmlBool _smlCommandMetaParse(SmlXmlParser *parser, char **format, char **type, SmlAnchor **anchor, unsigned int *size, int *maxobjsize, SmlError **error)
00555 {
00556 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p, %p, %p)", __func__, parser, format, type, anchor, size, maxobjsize, error);
00557 CHECK_ERROR_REF
00558 smlAssert(parser);
00559
00560 if (maxobjsize)
00561 *maxobjsize = -1;
00562
00563 if (xmlTextReaderIsEmptyElement(parser->reader))
00564 {
00565
00566 smlTrace(TRACE_EXIT, "%s - empty meta element", __func__);
00567 return TRUE;
00568 }
00569
00570 while (1) {
00571 if (!_smlXmlParserStep(parser)) {
00572 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
00573 goto error;
00574 }
00575
00576 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MEM)) {
00577
00578 smlTrace(TRACE_INTERNAL, "%s: Skipping mem node");
00579 if (!_smlXmlSkipNode(parser)) {
00580 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to skip mem node");
00581 goto error;
00582 }
00583 }
00584
00585 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META) && \
00586 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00587 break;
00588 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00589 smlErrorSet(error, SML_ERROR_GENERIC,
00590 "The element %s is not a start node in Command/Meta.",
00591 xmlTextReaderConstName(parser->reader));
00592 goto error;
00593 }
00594
00595 if (type && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TYPE)) {
00596 if (!_smlXmlParserGetString(parser, type, SML_ELEMENT_TYPE, error))
00597 goto error;
00598 } else if (anchor && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ANCHOR)) {
00599 if (!_smlAnchorParse(anchor, parser, error))
00600 goto error;
00601 } else if (format && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FORMAT)) {
00602 if (!_smlXmlParserGetString(parser, format, SML_ELEMENT_FORMAT, error))
00603 goto error;
00604 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MARK)) {
00605
00606 char *mark = NULL;
00607 if (!_smlXmlParserGetString(parser, &mark, SML_ELEMENT_MARK, error))
00608 goto error;
00609 smlSafeCFree(&mark);
00610 } else if (size && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SIZE)) {
00611 if (!_smlXmlParserGetID(parser, size, SML_ELEMENT_SIZE, error))
00612 goto error;
00613 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAXOBJSIZE)) {
00614
00615 unsigned int loc_maxobjsize = 0;
00616 if (!_smlXmlParserGetID(parser, &loc_maxobjsize, SML_ELEMENT_MAXOBJSIZE, error))
00617 goto error;
00618 if (maxobjsize)
00619 *maxobjsize = loc_maxobjsize;
00620 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_VERSION)) {
00621
00622 char *version = NULL;
00623 if (!_smlXmlParserGetString(parser, &version, SML_ELEMENT_VERSION, error))
00624 goto error;
00625 smlSafeCFree(&version);
00626 } else {
00627 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node for meta information: %s", xmlTextReaderConstName(parser->reader));
00628 goto error;
00629 }
00630 }
00631
00632 smlTrace(TRACE_EXIT, "%s", __func__);
00633 return TRUE;
00634
00635 error:
00636 if (format)
00637 *format = NULL;
00638 if (anchor)
00639 *anchor = NULL;
00640 if (type)
00641 *type = NULL;
00642 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00643 return FALSE;
00644 }
00645
00646 static SmlItem *_smlItemParse(SmlXmlParser *parser, SmlCommand *cmd, SmlCommandType type, SmlError **error)
00647 {
00648 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, parser, cmd, type, error);
00649 CHECK_ERROR_REF
00650 smlAssert(parser);
00651
00652 if (parser->gotMoreData) {
00653 smlErrorSet(error, SML_ERROR_GENERIC, "Last item already had more data set");
00654 goto error;
00655 }
00656
00657 SmlItem *item = smlItemNew(0, error);
00658 if (!item)
00659 goto error;
00660
00661
00662 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM) &&
00663 xmlTextReaderIsEmptyElement(parser->reader)) {
00664 smlTrace(TRACE_EXIT, "%s - empty item", __func__);
00665 return item;
00666 }
00667
00668 if (!_smlXmlParserStep(parser)) {
00669 smlErrorSet(error, SML_ERROR_GENERIC, "The first element inside of an Item structure cannot be parsed.");
00670 goto error_free_item;
00671 }
00672
00673 while (1) {
00674 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM) && \
00675 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00676 break;
00677 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00678 smlErrorSet(error, SML_ERROR_GENERIC,
00679 "The element %s is not a start node in Item.",
00680 xmlTextReaderConstName(parser->reader));
00681 goto error_free_item;
00682 }
00683
00684 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE)) {
00685 SmlLocation *source = NULL;
00686 if (!_smlLocationParse(&source, parser, error))
00687 goto error_free_item;
00688
00689 smlItemSetSource(item, source);
00690 smlLocationUnref(source);
00691 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET)) {
00692 SmlLocation *target = NULL;
00693 if (!_smlLocationParse(&target, parser, error))
00694 goto error_free_item;
00695
00696 smlItemSetTarget(item, target);
00697 smlLocationUnref(target);
00698 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE_PARENT)) {
00699 SmlLocation *source = NULL;
00700 if (!_smlLocationParse(&source, parser, error))
00701 goto error_free_item;
00702
00703 smlItemSetSourceParent(item, source);
00704 smlLocationUnref(source);
00705 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET_PARENT)) {
00706 SmlLocation *target = NULL;
00707 if (!_smlLocationParse(&target, parser, error))
00708 goto error_free_item;
00709
00710 smlItemSetTargetParent(item, target);
00711 smlLocationUnref(target);
00712 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
00713 switch (type) {
00714 case SML_COMMAND_TYPE_ALERT:
00715 if (!cmd) {
00716
00717
00718
00719
00720
00721 if (!_smlCommandMetaParse(parser, NULL, NULL, NULL, NULL, NULL, error))
00722 goto error_free_item;
00723 } else {
00724
00725 if (!_smlCommandMetaParse(parser, NULL, &(cmd->private.alert.contentType), &cmd->private.alert.anchor, NULL, &(cmd->private.alert.maxObjSize), error))
00726 goto error_free_item;
00727 }
00728 break;
00729 case SML_COMMAND_TYPE_ADD:
00730 case SML_COMMAND_TYPE_DELETE:
00731 case SML_COMMAND_TYPE_REPLACE:
00732 if (!_smlCommandMetaParse(parser, NULL, &(item->contenttype), NULL, &cmd->size, NULL, error))
00733 goto error_free_item;
00734 break;
00735 case SML_COMMAND_TYPE_RESULTS:
00736 case SML_COMMAND_TYPE_PUT:;
00737
00738
00739 if (!_smlCommandMetaParse(parser, NULL, &(item->contenttype), NULL, NULL, NULL, error))
00740 goto error_free_item;
00741
00742 if (!item->contenttype)
00743 goto error_free_item;
00744 break;
00745 default:
00746 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown command type");
00747 goto error_free_item;
00748 }
00749 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATA)) {
00750
00751
00752
00753
00754
00755 if (!xmlTextReaderIsEmptyElement(parser->reader)) {
00756 switch (type) {
00757 case SML_COMMAND_TYPE_ALERT:
00758 if (!_smlXmlParserStep(parser)) {
00759 smlErrorSet(error, SML_ERROR_GENERIC, "The next element after the starting Data element in an Item is missing.");
00760 goto error_free_item;
00761 }
00762
00763 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATA) &&
00764 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00765
00766
00767
00768
00769
00770 smlTrace(TRACE_INTERNAL, "%s: detected empty data element", __func__);
00771 break;
00772 }
00773
00774 SmlAnchor *anchor = NULL;
00775 if (xmlTextReaderNodeType(parser->reader) == XML_NODE_TEXT) {
00776
00777
00778
00779 anchor = smlTryMalloc0(sizeof(SmlAnchor), error);
00780 if (!anchor)
00781 goto error_free_item;
00782 anchor->next = g_strdup((char *)xmlTextReaderConstValue(parser->reader));
00783 } else {
00784
00785 if (!_smlAnchorParse(&anchor, parser, error))
00786 goto error_free_item;
00787 }
00788 item->anchor = anchor;
00789
00790 if (!_smlXmlParserStep(parser)) {
00791 smlErrorSet(error, SML_ERROR_GENERIC, "The closing Data element in an Item is missing.");
00792 goto error_free_item;
00793 }
00794 break;
00795 default:;
00796 char *data = NULL;
00797 unsigned int size = 0;
00798 if (!_smlXmlParserGetData(parser, &data, &size, SML_ELEMENT_DATA, error))
00799 goto error_free_item;
00800
00801 if (!smlItemAddData(item, data, size, error)) {
00802 smlSafeCFree(&data);
00803 goto error_free_item;
00804 }
00805
00806 smlSafeCFree(&data);
00807 }
00808 }
00809 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MOREDATA)) {
00810 if (parser->version == SML_VERSION_10) {
00811 smlErrorSet(error, SML_ERROR_GENERIC, "SyncML 1.0 does not allow MoreData");
00812 goto error_free_item;
00813 }
00814
00815 item->moreData = TRUE;
00816 parser->gotMoreData = TRUE;
00817 if (!_smlXmlParserStep(parser)) {
00818 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes2");
00819 goto error_free_item;
00820 }
00821
00822 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MOREDATA) && \
00823 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00824 if (!_smlXmlParserStep(parser)) {
00825 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes3");
00826 goto error_free_item;
00827 }
00828 }
00829 continue;
00830 } else {
00831 smlErrorSet(error, SML_ERROR_GENERIC, "The element Item does not support the child element %s.", xmlTextReaderConstName(parser->reader));
00832 goto error_free_item;
00833 }
00834
00835 if (!_smlXmlParserStep(parser)) {
00836 smlErrorSet(error, SML_ERROR_GENERIC, "The next element in an Item structure is missing.");
00837 goto error_free_item;
00838 }
00839 }
00840
00841 smlTrace(TRACE_EXIT, "%s", __func__);
00842 return item;
00843
00844 error_free_item:
00845 smlItemUnref(item);
00846 error:
00847 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00848 return NULL;
00849 }
00850
00851 static SmlCred *_smlCredParse(SmlXmlParser *parser, SmlError **error)
00852 {
00853 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, parser, error);
00854 CHECK_ERROR_REF
00855 smlAssert(parser);
00856 SmlCred *cred = NULL;
00857 char *format = NULL;
00858 char *type = NULL;
00859 char *data = NULL;
00860
00861 while (1) {
00862 if (!_smlXmlParserStep(parser)) {
00863 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
00864 goto error;
00865 }
00866
00867 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CRED) && \
00868 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00869 break;
00870 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00871 smlErrorSet(error, SML_ERROR_GENERIC,
00872 "The element %s is not a start node in Cred.",
00873 xmlTextReaderConstName(parser->reader));
00874 goto error;
00875 }
00876
00877 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
00878 if (!_smlCommandMetaParse(parser, &format, &type, NULL, NULL, NULL, error))
00879 goto error;
00880 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATA)) {
00881 if (!_smlXmlParserGetString(parser, &data, SML_ELEMENT_DATA, error))
00882 goto error;
00883 } else {
00884 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node %s", xmlTextReaderConstName(parser->reader));
00885 goto error;
00886 }
00887 }
00888
00889 cred = smlCredNewFromString(type, format, data, error);
00890
00891 error:
00892 if (data)
00893 smlSafeCFree(&data);
00894
00895 if (format)
00896 smlSafeCFree(&format);
00897
00898 if (type)
00899 smlSafeCFree(&type);
00900
00901 if (!smlErrorIsSet(error))
00902 {
00903 smlTrace(TRACE_EXIT, "%s: %p", __func__, cred);
00904 return cred;
00905 } else {
00906 if (cred)
00907 smlCredUnref(cred);
00908 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00909 return NULL;
00910 }
00911 }
00912
00913 static SmlChal *_smlChalParse(SmlXmlParser *parser, SmlError **error)
00914 {
00915 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, parser, error);
00916 CHECK_ERROR_REF
00917 smlAssert(parser);
00918 char *format = NULL;
00919 char *type = NULL;
00920 char *nonce = NULL;
00921
00922 while (1) {
00923 if (!_smlXmlParserStep(parser)) {
00924 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
00925 goto error;
00926 }
00927
00928 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CHAL) && \
00929 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
00930 break;
00931 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
00932 smlErrorSet(error, SML_ERROR_GENERIC,
00933 "The element %s is not a start node in Chal.",
00934 xmlTextReaderConstName(parser->reader));
00935 goto error;
00936 }
00937
00938 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
00939 if (!_smlChalMetaParse(parser, &format, &type, &nonce, error))
00940 goto error;
00941 } else {
00942 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node %s", xmlTextReaderConstName(parser->reader));
00943 goto error;
00944 }
00945 }
00946
00947 if (format && strcmp(format, SML_BASE64)) {
00948 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown format");
00949 goto error;
00950 }
00951
00952 SmlAuthType auth;
00953 if (!type || !strcmp(type, SML_AUTH_BASIC)) {
00954 auth = SML_AUTH_TYPE_BASIC;
00955 } else if (!strcmp(type, SML_AUTH_MD5)) {
00956 auth = SML_AUTH_TYPE_MD5;
00957 } else {
00958 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown type");
00959 goto error;
00960 }
00961
00962 if (format)
00963 smlSafeCFree(&format);
00964 if (type)
00965 smlSafeCFree(&type);
00966
00967 SmlChal *chal = NULL;
00968 if (nonce || auth == SML_AUTH_TYPE_MD5)
00969 chal = smlChalNewFromBase64(auth, nonce, error);
00970 else
00971 chal = smlChalNew(auth, error);
00972 if (!chal)
00973 goto error;
00974
00975 if (nonce)
00976 smlSafeCFree(&nonce);
00977
00978 smlTrace(TRACE_EXIT, "%s: %p", __func__, chal);
00979 return chal;
00980
00981 error:
00982 if (format)
00983 smlSafeCFree(&format);
00984 if (type)
00985 smlSafeCFree(&type);
00986 if (nonce)
00987 smlSafeCFree(&nonce);
00988 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00989 return NULL;
00990 }
00991
00992 static SmlBool _smlChangeParse(SmlXmlParser *parser, SmlCommand **cmd, SmlCommandType type, const char *name, SmlError **error)
00993 {
00994 smlTrace(TRACE_ENTRY, "%s(%p, %i, %s, %p)", __func__, parser, type, VA_STRING(name), error);
00995 CHECK_ERROR_REF
00996 smlAssert(parser);
00997 smlAssert(name);
00998 char *contenttype = NULL;
00999
01000 *cmd = smlCommandNew(type, error);
01001 if (!*cmd)
01002 goto error;
01003 (*cmd)->refCount = 1;
01004
01005 while (1) {
01006 if (!_smlXmlParserStep(parser)) {
01007 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01008 goto error_free_cmd;
01009 }
01010
01011 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), name) && \
01012 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01013 break;
01014 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01015 smlErrorSet(error, SML_ERROR_GENERIC,
01016 "The element %s is not a start node in %s.",
01017 xmlTextReaderConstName(parser->reader), name);
01018 goto error_free_cmd;
01019 }
01020
01021 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
01022 if (!_smlXmlParserGetID(parser, &((*cmd)->cmdID), SML_ELEMENT_CMDID, error))
01023 goto error_free_cmd;
01024 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM)) {
01025 SmlItem *item = _smlItemParse(parser, *cmd, type, error);
01026 if (!item)
01027 goto error_free_cmd;
01028 (*cmd)->private.change.items = g_list_append((*cmd)->private.change.items, item);
01029 if (!(*cmd)->private.change.items)
01030 {
01031 smlItemUnref(item);
01032 smlErrorSet(error, SML_ERROR_GENERIC, "g_list_append for item list of change command failed.");
01033 goto error_free_cmd;
01034 }
01035 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
01036 if (!_smlCommandMetaParse(parser, NULL, &contenttype, NULL, &(*cmd)->size, NULL, error))
01037 goto error_free_cmd;
01038 } else {
01039 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
01040 goto error_free_cmd;
01041 }
01042 }
01043
01044 if (!(*cmd)->cmdID) {
01045 smlErrorSet(error, SML_ERROR_GENERIC, "No cmdid set");
01046 goto error_free_cmd;
01047 }
01048
01049 if (!(*cmd)->private.change.items ||
01050 !g_list_length((*cmd)->private.change.items)) {
01051 smlErrorSet(error, SML_ERROR_GENERIC, "No items set");
01052 goto error_free_cmd;
01053 }
01054
01055
01056 guint i;
01057 for (i=0; i < g_list_length((*cmd)->private.change.items); i++)
01058 {
01059 SmlItem *item = g_list_nth_data((*cmd)->private.change.items, i);
01060 if (item->contenttype == NULL && contenttype) {
01061 item->contenttype = g_strdup(contenttype);
01062 }
01063 }
01064 if (contenttype)
01065 smlSafeCFree(&contenttype);
01066
01067 for (i=0; i < g_list_length((*cmd)->private.change.items); i++)
01068 {
01069 SmlItem *item = g_list_nth_data((*cmd)->private.change.items, i);
01070 if ((*cmd)->size && !item->size)
01071 item->size = (*cmd)->size;
01072 }
01073
01074 switch (type) {
01075 case SML_COMMAND_TYPE_ADD:
01076 (*cmd)->private.change.type = SML_CHANGE_ADD;
01077 break;
01078 case SML_COMMAND_TYPE_REPLACE:
01079 (*cmd)->private.change.type = SML_CHANGE_REPLACE;
01080 break;
01081 case SML_COMMAND_TYPE_DELETE:
01082 (*cmd)->private.change.type = SML_CHANGE_DELETE;
01083 break;
01084 default:
01085 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown change type set");
01086 goto error_free_cmd;
01087 }
01088
01089 if (!(*cmd)->source)
01090 {
01091 SmlItem *item = g_list_nth_data((*cmd)->private.change.items, 0);
01092 if (item->source) {
01093 (*cmd)->source = smlLocationClone(item->source, error);
01094 if (!(*cmd)->source)
01095 goto error_free_cmd;
01096 }
01097 }
01098
01099 if (!(*cmd)->target)
01100 {
01101 SmlItem *item = g_list_nth_data((*cmd)->private.change.items, 0);
01102 if (item->target) {
01103 (*cmd)->target = smlLocationClone(item->target, error);
01104 if (!(*cmd)->target)
01105 goto error_free_cmd;
01106 }
01107 }
01108
01109
01110 if (!_smlXmlParserStep(parser)) {
01111 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01112 goto error_free_cmd;
01113 }
01114
01115 smlTrace(TRACE_EXIT, "%s: %p", __func__, *cmd);
01116 return TRUE;
01117
01118 error_free_cmd:
01119 smlCommandUnref(*cmd);
01120 error:
01121 if (contenttype)
01122 smlSafeCFree(&contenttype);
01123 *cmd = NULL;
01124 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01125 return FALSE;
01126 }
01127
01128 static SmlBool _smlMessageParseSynchdrMeta(SmlXmlParser *parser, unsigned int *maxmsgsize, unsigned int *maxobjsize, char **emi, SmlError **error)
01129 {
01130 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, parser, maxmsgsize, maxobjsize, error);
01131 CHECK_ERROR_REF
01132 smlAssert(parser);
01133 smlAssert(maxmsgsize);
01134 smlAssert(maxobjsize);
01135 smlAssert(emi);
01136
01137
01138 while (1) {
01139 if (!_smlXmlParserStep(parser)) {
01140 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01141 goto error;
01142 }
01143
01144 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META) && \
01145 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01146 break;
01147 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01148 smlErrorSet(error, SML_ERROR_GENERIC,
01149 "The element %s is not a start node in SyncHdr/Meta.",
01150 xmlTextReaderConstName(parser->reader));
01151 goto error;
01152 }
01153
01154 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAXMSGSIZE)) {
01155 if (!_smlXmlParserGetID(parser, maxmsgsize, SML_ELEMENT_MAXMSGSIZE, error))
01156 goto error;
01157 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAXOBJSIZE)) {
01158 if (!_smlXmlParserGetID(parser, maxobjsize, SML_ELEMENT_MAXOBJSIZE, error))
01159 goto error;
01160 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_EMI)) {
01161 if (!_smlXmlParserGetString(parser, emi, SML_ELEMENT_EMI, error))
01162 goto error;
01163 } else {
01164 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node. expected MaxMsgSize, MaxObjSize or EMI. Instead of that: %s", xmlTextReaderConstName(parser->reader));
01165 goto error;
01166 }
01167 }
01168
01169 if (!(*maxmsgsize) && !(*maxobjsize)) {
01170 smlErrorSet(error, SML_ERROR_GENERIC, "No maxmsgsize set");
01171 goto error;
01172 }
01173
01174 smlTrace(TRACE_EXIT, "%s", __func__);
01175 return TRUE;
01176
01177 error:
01178 *maxmsgsize = 0;
01179 *maxobjsize = 0;
01180 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01181 return FALSE;
01182 }
01183
01184 static SmlBool _smlAlertParse(SmlXmlParser *parser, SmlCommand **cmd, SmlError **error)
01185 {
01186 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
01187 CHECK_ERROR_REF
01188 smlAssert(parser);
01189 smlAssert(cmd);
01190
01191 *cmd = smlCommandNew(SML_COMMAND_TYPE_ALERT, error);
01192 if (!*cmd)
01193 goto error;
01194 (*cmd)->refCount = 1;
01195 (*cmd)->private.alert.maxObjSize = -1;
01196
01197 while (1) {
01198 if (!_smlXmlParserStep(parser)) {
01199 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01200 goto error_free_cmd;
01201 }
01202
01203 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ALERT) && \
01204 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01205 break;
01206 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01207 smlErrorSet(error, SML_ERROR_GENERIC,
01208 "The element %s is not a start node in Alert.",
01209 xmlTextReaderConstName(parser->reader));
01210 goto error_free_cmd;
01211 }
01212
01213 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
01214 if (!_smlXmlParserGetID(parser, &((*cmd)->cmdID), SML_ELEMENT_CMDID, error))
01215 goto error_free_cmd;
01216 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM)) {
01217 SmlItem *item = _smlItemParse(parser, (*cmd), SML_COMMAND_TYPE_ALERT, error);
01218 if (!item)
01219 goto error_free_cmd;
01220
01221 (*cmd)->target = item->target;
01222 item->target = NULL;
01223 (*cmd)->source = item->source;
01224 item->source = NULL;
01225
01226 smlItemUnref(item);
01227 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATA)) {
01228 unsigned int id = 0;
01229 if (!_smlXmlParserGetID(parser, &id, SML_ELEMENT_DATA, error))
01230 goto error_free_cmd;
01231 (*cmd)->private.alert.type = smlAlertTypeConvert(id, error);
01232 if ((*cmd)->private.alert.type == SML_ALERT_UNKNOWN &&
01233 *error != NULL)
01234 goto error_free_cmd;
01235 } else {
01236 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node %s", xmlTextReaderConstName(parser->reader));
01237 goto error_free_cmd;
01238 }
01239 }
01240
01241 if (!(*cmd)->private.alert.type) {
01242 smlErrorSet(error, SML_ERROR_GENERIC, "No alert type set");
01243 goto error_free_cmd;
01244 }
01245
01246
01247 if (!_smlXmlParserStep(parser)) {
01248 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01249 goto error_free_cmd;
01250 }
01251
01252 smlTrace(TRACE_EXIT, "%s", __func__);
01253 return TRUE;
01254
01255 error_free_cmd:
01256 smlCommandUnref(*cmd);
01257 error:
01258 *cmd = NULL;
01259 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01260 return FALSE;
01261 }
01262
01263 static SmlParserResult _smlCommandSyncParse(SmlXmlParser *parser, SmlCommand **cmd, SmlError **error)
01264 {
01265 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
01266 CHECK_ERROR_REF
01267 smlAssert(parser);
01268 smlAssert(cmd);
01269
01270 *cmd = smlCommandNew(SML_COMMAND_TYPE_SYNC, error);
01271 if (!*cmd)
01272 goto error;
01273 (*cmd)->private.sync.maxObjSize = -1;
01274
01275 while (1) {
01276 if (!_smlXmlParserStep(parser)) {
01277 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01278 goto error_free_cmd;
01279 }
01280
01281 if (xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE && !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNC))
01282 break;
01283 else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01284 smlErrorSet(error, SML_ERROR_GENERIC,
01285 "The element %s is not a start node in Sync.",
01286 xmlTextReaderConstName(parser->reader));
01287 goto error_free_cmd;
01288 }
01289
01290 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ADD) || \
01291 !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_REPLACE) || \
01292 !strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DELETE))
01293 break;
01294
01295 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
01296 if (!_smlXmlParserGetID(parser, &((*cmd)->cmdID), SML_ELEMENT_CMDID, error))
01297 goto error_free_cmd;
01298 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM)) {
01299 SmlItem *item = _smlItemParse(parser, (*cmd), SML_COMMAND_TYPE_SYNC, error);
01300 if (!item)
01301 goto error_free_cmd;
01302 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
01303 if (!_smlCommandMetaParse(parser, NULL, NULL, NULL, NULL, &((*cmd)->private.sync.maxObjSize), error))
01304 goto error;
01305 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET)) {
01306 if (!_smlLocationParse(&(*cmd)->target, parser, error))
01307 goto error_free_cmd;
01308 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE)) {
01309 if (!_smlLocationParse(&(*cmd)->source, parser, error))
01310 goto error_free_cmd;
01311 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_NUMBEROFCHANGES)) {
01312 (*cmd)->private.sync.hasNumChanged = TRUE;
01313 if (!_smlXmlParserGetID(parser, &((*cmd)->private.sync.numChanged), SML_ELEMENT_NUMBEROFCHANGES, error))
01314 goto error_free_cmd;
01315 } else {
01316 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node: %s", xmlTextReaderConstName(parser->reader));
01317 goto error_free_cmd;
01318 }
01319 }
01320
01321 smlTrace(TRACE_EXIT, "%s", __func__);
01322 return TRUE;
01323
01324 error_free_cmd:
01325 smlCommandUnref(*cmd);
01326 error:
01327 *cmd = NULL;
01328 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01329 return FALSE;
01330 }
01331
01332 static SmlMapItem *_smlMapItemParse(SmlXmlParser *parser, SmlError **error)
01333 {
01334 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, parser, error);
01335 CHECK_ERROR_REF
01336 smlAssert(parser);
01337
01338 SmlMapItem *item = smlTryMalloc0(sizeof(SmlMapItem), error);
01339 if (!item)
01340 goto error;
01341 item->refCount = 1;
01342
01343 while (1) {
01344 if (!_smlXmlParserStep(parser)) {
01345 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01346 goto error_free_item;
01347 }
01348
01349 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAPITEM) && \
01350 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01351 break;
01352 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01353 smlErrorSet(error, SML_ERROR_GENERIC,
01354 "The element %s is not a start node in MapItem.",
01355 xmlTextReaderConstName(parser->reader));
01356 goto error_free_item;
01357 }
01358
01359 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE)) {
01360 if (!_smlLocationParse(&item->source, parser, error))
01361 goto error_free_item;
01362 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET)) {
01363 if (!_smlLocationParse(&item->target, parser, error))
01364 goto error_free_item;
01365 } else {
01366 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node %s", xmlTextReaderConstName(parser->reader));
01367 goto error_free_item;
01368 }
01369 }
01370
01371 smlTrace(TRACE_EXIT, "%s", __func__);
01372 return item;
01373
01374 error_free_item:
01375 smlMapItemUnref(item);
01376 error:
01377 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01378 return NULL;
01379 }
01380
01381 static SmlBool _smlCommandMapParse(SmlXmlParser *parser, SmlCommand **cmd, SmlError **error)
01382 {
01383 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
01384 CHECK_ERROR_REF
01385 smlAssert(parser);
01386 smlAssert(cmd);
01387
01388 *cmd = smlCommandNew(SML_COMMAND_TYPE_MAP, error);
01389 if (!*cmd)
01390 goto error;
01391 (*cmd)->refCount = 1;
01392
01393 while (1) {
01394 if (!_smlXmlParserStep(parser)) {
01395 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01396 goto error_free_cmd;
01397 }
01398
01399 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAP) && \
01400 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01401 break;
01402 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01403 smlErrorSet(error, SML_ERROR_GENERIC,
01404 "The element %s is not a start node in Map.",
01405 xmlTextReaderConstName(parser->reader));
01406 goto error_free_cmd;
01407 }
01408
01409 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
01410 if (!_smlXmlParserGetID(parser, &((*cmd)->cmdID), SML_ELEMENT_CMDID, error))
01411 goto error_free_cmd;
01412 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAPITEM)) {
01413 SmlMapItem *item = _smlMapItemParse(parser, error);
01414 if (!item)
01415 goto error_free_cmd;
01416 (*cmd)->private.map.items = g_list_append((*cmd)->private.map.items, item);
01417 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET)) {
01418 if (!_smlLocationParse(&(*cmd)->target, parser, error))
01419 goto error_free_cmd;
01420 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE)) {
01421 if (!_smlLocationParse(&(*cmd)->source, parser, error))
01422 goto error_free_cmd;
01423 } else {
01424 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
01425 goto error_free_cmd;
01426 }
01427 }
01428
01429
01430 if (!_smlXmlParserStep(parser)) {
01431 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01432 goto error_free_cmd;
01433 }
01434
01435 smlTrace(TRACE_EXIT, "%s", __func__);
01436 return TRUE;
01437
01438 error_free_cmd:
01439 smlCommandUnref(*cmd);
01440 error:
01441 *cmd = NULL;
01442 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01443 return FALSE;
01444 }
01445
01446 static SmlBool _smlCommandAccessParse(SmlXmlParser *parser, SmlCommand **cmd, SmlCommandType type, SmlError **error)
01447 {
01448 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, parser, cmd, type, error);
01449 CHECK_ERROR_REF
01450 smlAssert(parser);
01451 smlAssert(cmd);
01452 char *contenttype = NULL;
01453
01454 *cmd = smlCommandNew(type, error);
01455 if (!*cmd)
01456 goto error;
01457 (*cmd)->refCount = 1;
01458
01459 while (1) {
01460 if (!_smlXmlParserStep(parser)) {
01461 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01462 goto error_free_cmd;
01463 }
01464
01465 if ((*cmd)->type == SML_COMMAND_TYPE_PUT &&!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_PUT) && \
01466 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01467 break;
01468 } else if ((*cmd)->type == SML_COMMAND_TYPE_GET &&!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_GET) && \
01469 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01470 break;
01471 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01472 smlErrorSet(error, SML_ERROR_GENERIC,
01473 "The element %s is not a start node in Put or Get.",
01474 xmlTextReaderConstName(parser->reader));
01475 goto error_free_cmd;
01476 }
01477
01478 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
01479 if (!_smlXmlParserGetID(parser, &((*cmd)->cmdID), SML_ELEMENT_CMDID, error))
01480 goto error_free_cmd;
01481 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM)) {
01482 (*cmd)->private.access.item = _smlItemParse(parser, (*cmd), (*cmd)->type, error);
01483 if (!(*cmd)->private.access.item)
01484 goto error_free_cmd;
01485
01486 (*cmd)->target = (*cmd)->private.access.item->target;
01487 (*cmd)->private.access.item->target = NULL;
01488 (*cmd)->source = (*cmd)->private.access.item->source;
01489 (*cmd)->private.access.item->source = NULL;
01490 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
01491 char *format = NULL;
01492 if (!_smlCommandMetaParse(parser, &format, &contenttype, NULL, NULL, NULL, error))
01493 goto error_free_cmd;
01494 if (format) smlSafeCFree(&format);
01495 } else {
01496 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
01497 goto error_free_cmd;
01498 }
01499 }
01500
01501 if (!(*cmd)->private.access.item) {
01502 smlErrorSet(error, SML_ERROR_GENERIC, "Put/Get is missing item");
01503 goto error_free_cmd;
01504 }
01505
01506
01507
01508 if (!(*cmd)->private.access.item->contenttype && contenttype)
01509 (*cmd)->private.access.item->contenttype = g_strdup(contenttype);
01510
01511 if (contenttype)
01512 smlSafeCFree(&contenttype);
01513
01514
01515 if (!_smlXmlParserStep(parser)) {
01516 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01517 goto error_free_cmd;
01518 }
01519
01520 smlTrace(TRACE_EXIT, "%s", __func__);
01521 return TRUE;
01522
01523 error_free_cmd:
01524 smlCommandUnref(*cmd);
01525 error:
01526 *cmd = NULL;
01527 if (contenttype)
01528 smlSafeCFree(&contenttype);
01529 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01530 return FALSE;
01531 }
01532
01533 static SmlBool _smlResultsParse(SmlXmlParser *parser, SmlCommand **cmd, SmlError **error)
01534 {
01535 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
01536 CHECK_ERROR_REF
01537 smlAssert(parser);
01538 smlAssert(cmd);
01539 char *contenttype = NULL;
01540 char *locURI = NULL;
01541
01542 *cmd = smlCommandNew(SML_COMMAND_TYPE_RESULTS, error);
01543 if (!*cmd)
01544 goto error;
01545 (*cmd)->refCount = 1;
01546
01547 (*cmd)->private.results.status = smlTryMalloc0(sizeof(SmlStatus), error);
01548 if (!(*cmd)->private.results.status)
01549 goto error;
01550 (*cmd)->private.results.status->refCount = 1;
01551 (*cmd)->private.results.status->result = (*cmd);
01552 (*cmd)->private.results.status->type = SML_COMMAND_TYPE_RESULTS;
01553
01554 while (1) {
01555 if (!_smlXmlParserStep(parser)) {
01556 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01557 goto error_free_cmd;
01558 }
01559
01560 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_RESULTS) && \
01561 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01562 break;
01563 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
01564 smlErrorSet(error, SML_ERROR_GENERIC,
01565 "The element %s is not a start node in Results.",
01566 xmlTextReaderConstName(parser->reader));
01567 goto error_free_cmd;
01568 }
01569
01570
01571 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
01572 if (!_smlXmlParserGetID(parser, &((*cmd)->cmdID), SML_ELEMENT_CMDID, error))
01573 goto error_free_cmd;
01574 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MSGREF)) {
01575 if (!_smlXmlParserGetID(parser, &((*cmd)->private.results.status->msgRef), SML_ELEMENT_MSGREF, error))
01576 goto error_free_cmd;
01577 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDREF)) {
01578 if (!_smlXmlParserGetID(parser, &((*cmd)->private.results.status->cmdRef), SML_ELEMENT_CMDREF, error))
01579 goto error_free_cmd;
01580 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCEREF)) {
01581 if (!_smlXmlParserGetString(parser, &locURI, SML_ELEMENT_SOURCEREF, error))
01582 goto error_free_cmd;
01583
01584 (*cmd)->private.results.status->sourceRef = smlLocationNew(locURI, NULL, error);
01585 smlSafeCFree(&locURI);
01586 if (!(*cmd)->private.results.status->sourceRef)
01587 goto error_free_cmd;
01588 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGETREF)) {
01589 if (!_smlXmlParserGetString(parser, &locURI, SML_ELEMENT_TARGETREF, error))
01590 goto error_free_cmd;
01591
01592 (*cmd)->private.results.status->targetRef = smlLocationNew(locURI, NULL, error);
01593 smlSafeCFree(&locURI);
01594 if (!(*cmd)->private.results.status->targetRef)
01595 goto error_free_cmd;
01596 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM)) {
01597 (*cmd)->private.results.status->item = _smlItemParse(parser, (*cmd), (*cmd)->type, error);
01598 if (!(*cmd)->private.results.status->item)
01599 goto error_free_cmd;
01600
01601 (*cmd)->target = (*cmd)->private.results.status->item->target;
01602 (*cmd)->private.results.status->item->target = NULL;
01603 (*cmd)->source = (*cmd)->private.results.status->item->source;
01604 (*cmd)->private.results.status->item->source = NULL;
01605 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
01606
01607 char *format = NULL;
01608 if (!_smlCommandMetaParse(parser, &format, &contenttype, NULL, NULL, NULL, error))
01609 goto error_free_cmd;
01610 if (format) smlSafeCFree(&format);
01611 } else {
01612 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
01613 goto error_free_cmd;
01614 }
01615 }
01616
01617 if (!(*cmd)->private.results.status->item) {
01618 smlErrorSet(error, SML_ERROR_GENERIC, "Result is missing item");
01619 goto error_free_cmd;
01620 }
01621
01622
01623
01624 if (!(*cmd)->private.results.status->item->contenttype) {
01625 if (!contenttype) {
01626 smlErrorSet(error, SML_ERROR_GENERIC, "Result is missing content type");
01627 goto error_free_cmd;
01628 }
01629
01630 (*cmd)->private.results.status->item->contenttype = g_strdup(contenttype);
01631 }
01632
01633 if (contenttype)
01634 smlSafeCFree(&contenttype);
01635
01636
01637 if (!_smlXmlParserStep(parser)) {
01638 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01639 goto error_free_cmd;
01640 }
01641
01642 smlTrace(TRACE_EXIT, "%s", __func__);
01643 return TRUE;
01644
01645 error_free_cmd:
01646 smlCommandUnref(*cmd);
01647 error:
01648 *cmd = NULL;
01649 if (contenttype)
01650 smlSafeCFree(&contenttype);
01651 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01652 return FALSE;
01653 }
01654
01655 static SmlBool _smlXmlParserFixBrokenItemData(
01656 const char *data, unsigned int size,
01657 char **fixed_data, unsigned int *fixed_size,
01658 SmlError **error)
01659 {
01660 smlTrace(TRACE_ENTRY, "%s(%p, %d, %p, %p, %p)", __func__, data, size, fixed_data, fixed_size, error);
01661 CHECK_ERROR_REF
01662 smlAssert(data);
01663 smlAssert(size);
01664 smlAssert(fixed_data);
01665 smlAssert(fixed_size);
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678 *fixed_size = size;
01679 *fixed_data = smlTryMalloc0(size + 1, error);
01680 if (!*fixed_data)
01681 {
01682 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
01683 return FALSE;
01684 }
01685 memcpy(*fixed_data, data, size);
01686 const char *position = *fixed_data;
01687
01688 while (position + 1 < *fixed_data + *fixed_size)
01689 {
01690
01691 const char *byte = position + 1;
01692 if (*byte != 0) {
01693
01694 position++;
01695 continue;
01696 }
01697 smlTrace(TRACE_INTERNAL, "%s: Found NULL byte in XML document at %p.", __func__, position);
01698
01699
01700
01701
01702 const char *last_utf16 = position;
01703 while (last_utf16 + 1 < *fixed_data + *fixed_size &&
01704 *((char *)(last_utf16 + 1)) == 0)
01705 {
01706 last_utf16 += 2;
01707 }
01708
01709
01710 last_utf16--;
01711
01712
01713 smlTrace(TRACE_INTERNAL, "%s: Converting %d bytes ...", __func__, last_utf16 - position + 1);
01714 GError *gerror = NULL;
01715 size_t read_bytes = 0;
01716 size_t written_bytes = 0;
01717 gchar *conv_string = g_convert(
01718 position, (last_utf16 - position + 1),
01719 "UTF-8", "UTF-16",
01720 &read_bytes, &written_bytes,
01721 &gerror);
01722 if (gerror != NULL)
01723 {
01724 smlErrorSet(
01725 error, SML_ERROR_GENERIC,
01726 "Character conversion from UTF-16 to UTF-8 failed. %s",
01727 gerror->message);
01728 g_error_free(gerror);
01729 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
01730 return FALSE;
01731 }
01732 smlTrace(TRACE_INTERNAL, "%s: read %d --> written %d --> %d ::= %s", __func__, read_bytes, written_bytes, strlen(conv_string), conv_string);
01733
01734
01735 char *new_data = smlTryMalloc0(*fixed_size - read_bytes + written_bytes + 1, error);
01736 if (!new_data)
01737 {
01738 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
01739 return FALSE;
01740 }
01741 memcpy(new_data, *fixed_data, (size_t) position - (size_t) *fixed_data);
01742 memcpy(new_data + (size_t) position - (size_t) *fixed_data, conv_string, written_bytes);
01743 memcpy(new_data + (size_t) position - (size_t) *fixed_data + written_bytes,
01744 position + read_bytes, *fixed_size - ( (size_t) position - (size_t) *fixed_data ) - read_bytes );
01745
01746
01747 *fixed_size = *fixed_size - read_bytes + written_bytes;
01748 position = new_data + (position - *fixed_data) + written_bytes;
01749 smlSafeCFree(fixed_data);
01750 *fixed_data = new_data;
01751 new_data = NULL;
01752 smlSafeCFree(&conv_string);
01753
01754 smlTrace(TRACE_INTERNAL, "%s: Converted UTF-16 string to UTF-8", __func__);
01755 }
01756 smlTrace(TRACE_INTERNAL, "%s: Correctly encoded: %s", __func__, *fixed_data);
01757
01758
01759
01760
01761
01762
01763 position = *fixed_data;
01764
01765 while (position + 1 < *fixed_data + *fixed_size)
01766 {
01767
01768 const char *limit_item_start = strstr(position, "<Item>");
01769 if (! limit_item_start)
01770 {
01771 smlTrace(TRACE_EXIT, "%s - no (more) Item found", __func__);
01772 return TRUE;
01773 } else {
01774 smlTrace(TRACE_INTERNAL, "%s - Item found", __func__);
01775 }
01776 const char *limit_item_end = strstr(limit_item_start, "</Item>");
01777 if (! limit_item_end)
01778 {
01779 g_warning("%s - no end of Item found.", __func__);
01780 smlTrace(TRACE_EXIT, "%s - no end of Item found", __func__);
01781 return TRUE;
01782 } else {
01783 smlTrace(TRACE_INTERNAL, "%s - end of Item found", __func__);
01784 }
01785 if (limit_item_start >= limit_item_end)
01786 {
01787
01788 position = limit_item_end + strlen("</Item>");
01789 continue;
01790 }
01791
01792
01793 const char *limit_data_start = strstr(limit_item_start, "<Data>");
01794 if (! limit_data_start)
01795 {
01796 smlTrace(TRACE_EXIT, "%s - no Data found", __func__);
01797 return TRUE;
01798 } else {
01799 smlTrace(TRACE_INTERNAL, "%s - Data found", __func__);
01800 }
01801 const char *limit_data_end = strstr(limit_data_start, "</Data>");
01802 if (! limit_data_end)
01803 {
01804 g_warning("%s - no end of Data found.", __func__);
01805 smlTrace(TRACE_EXIT, "%s - no end of Data found", __func__);
01806 return TRUE;
01807 } else {
01808 smlTrace(TRACE_INTERNAL, "%s - end of Data found", __func__);
01809 }
01810 if (limit_data_start >= limit_data_end)
01811 {
01812
01813 position = limit_data_end + strlen("</Data>");
01814 continue;
01815 }
01816
01817
01818 if (limit_item_start >= limit_data_start ||
01819 limit_data_start >= limit_data_end ||
01820 limit_data_end >= limit_item_end)
01821 {
01822
01823
01824
01825 position = limit_item_end + strlen("</Item>");
01826 continue;
01827 }
01828
01829
01830 const char *cdata_start = strstr(limit_data_start, "<![CDATA[");
01831 const char *cdata_end = NULL;
01832 if (cdata_start)
01833 cdata_end = strstr(cdata_start, "]]");
01834 if (cdata_start && cdata_end &&
01835 limit_data_start < cdata_start &&
01836 cdata_start < cdata_end &&
01837 cdata_end < limit_data_end)
01838 {
01839
01840 position = limit_item_end + strlen("</Item>");
01841 continue;
01842 }
01843
01844
01845 if (g_strstr_len(
01846 limit_data_start + strlen("<Data>"),
01847 limit_data_end - limit_data_start - strlen("<Data>"),
01848 "<"))
01849 {
01850
01851 position = limit_item_end + strlen("</Item>");
01852 continue;
01853 }
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866 smlTrace(TRACE_INTERNAL, "%s: There is data which is not CDATA.", __func__);
01867
01868
01869
01870
01871
01872 char *new_data = smlTryMalloc0(*fixed_size + strlen("<![CDATA[]]>") + 1, error);
01873 if (!new_data)
01874 {
01875 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
01876 return FALSE;
01877 }
01878 size_t before_size = limit_data_start + strlen("<Data>") - *fixed_data;
01879 size_t data_size = limit_data_end - limit_data_start - strlen("<Data>");
01880 size_t after_size = *fixed_size - before_size - data_size;
01881
01882 smlTrace(TRACE_INTERNAL, "%s: %i = %i + %i +%i", __func__,
01883 *fixed_size, before_size, data_size, after_size);
01884
01885 memcpy(new_data, *fixed_data, before_size);
01886 memcpy(new_data + before_size, "<![CDATA[", strlen ("<![CDATA["));
01887 memcpy(new_data + before_size + strlen ("<![CDATA["),
01888 limit_data_start + strlen("<Data>"),
01889 data_size);
01890 memcpy(new_data + before_size + strlen ("<![CDATA[") + data_size,
01891 "]]>", strlen("]]>"));
01892 memcpy(new_data + before_size + strlen ("<![CDATA[]]>") + data_size,
01893 limit_data_end,
01894 after_size);
01895 smlSafeCFree(fixed_data);
01896 *fixed_data = new_data;
01897 new_data = NULL;
01898 *fixed_size += strlen("<![CDATA[]]>");
01899
01900 position = *fixed_data +
01901 before_size + strlen ("<![CDATA[]]>") +
01902 data_size + strlen("</Data></Item>");
01903 smlTrace(TRACE_INTERNAL, "%s: CDATA inserted", __func__);
01904 }
01905
01906 smlTrace(TRACE_EXIT, "%s", __func__);
01907 return TRUE;
01908 }
01909
01915 SmlBool smlXmlParserStart(SmlXmlParser *parser, const char *data, unsigned int size, SmlError **error)
01916 {
01917 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, parser, data, size, error);
01918 CHECK_ERROR_REF
01919 smlAssert(parser);
01920 smlAssert(data);
01921 smlAssert(size);
01922
01923
01924
01925
01926
01927
01928
01929
01930 parser->data = NULL;
01931 parser->size = 0;
01932 if (! _smlXmlParserFixBrokenItemData(
01933 data, size, &(parser->data), &(parser->size), error))
01934 {
01935 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
01936 return FALSE;
01937 }
01938
01939 char *debugstr = smlPrintBinary(parser->data, parser->size);
01940 smlTrace(TRACE_INTERNAL, "Xml input: %s", debugstr);
01941 smlLog("received-%i.xml", parser->data, parser->size);
01942 smlSafeCFree(&debugstr);
01943
01944 parser->got_command = FALSE;
01945
01946
01947 parser->reader = xmlReaderForMemory(parser->data, parser->size, "/", NULL, XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOCDATA);
01948 if (!parser->reader) {
01949 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to create new reader");
01950 goto error;
01951 }
01952 xmlSubstituteEntitiesDefault(1);
01953
01954
01955 if (!_smlXmlParserExpectNode(parser, XML_NODE_START, FALSE, SML_ELEMENT_SYNCML, error))
01956 goto error_free_reader;
01957
01958
01959 if (!_smlXmlParserExpectNode(parser, XML_NODE_START, FALSE, SML_ELEMENT_SYNCHDR, error))
01960 goto error_free_reader;
01961
01962 smlTrace(TRACE_EXIT, "%s", __func__);
01963 return TRUE;
01964
01965 error_free_reader:
01966 xmlFreeTextReader(parser->reader);
01967 error:
01968 parser->reader = NULL;
01969 if (parser->data)
01970 smlSafeCFree(&(parser->data));
01971 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01972 return FALSE;
01973 }
01974
01975 SmlBool smlXmlParserEnd(SmlXmlParser *parser, SmlBool *final, SmlBool *end, SmlError **error)
01976 {
01977 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, parser, final, end, error);
01978 CHECK_ERROR_REF
01979 smlAssert(parser);
01980 SmlBool got_final = FALSE;
01981
01982
01983 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FINAL)) {
01984 got_final = TRUE;
01985 if (!_smlXmlParserStep(parser)) {
01986 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01987 goto error;
01988 }
01989
01990 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FINAL) && \
01991 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
01992 if (!_smlXmlParserStep(parser)) {
01993 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
01994 goto error;
01995 }
01996 }
01997 }
01998
01999 if (final)
02000 *final = got_final;
02001
02002
02003
02004 if (end) {
02005 if (got_final)
02006 *end = parser->got_command ? FALSE : TRUE;
02007 else
02008 *end = FALSE;
02009 }
02010
02011
02012 if (strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCBODY) ||
02013 (!xmlTextReaderIsEmptyElement(parser->reader) &&
02014 xmlTextReaderNodeType(parser->reader) != XML_NODE_CLOSE
02015 )
02016 ) {
02017 smlErrorSet(error, SML_ERROR_GENERIC, "Wrong closing syncbody node");
02018 goto error;
02019 }
02020
02021
02022 if (!_smlXmlParserExpectNode(parser, XML_NODE_CLOSE, FALSE, SML_ELEMENT_SYNCML, error))
02023 goto error;
02024
02025 xmlFreeTextReader(parser->reader);
02026 parser->reader = NULL;
02027 parser->size = 0;
02028 smlSafeCFree(&(parser->data));
02029
02030 smlTrace(TRACE_EXIT, "%s", __func__);
02031 return TRUE;
02032
02033 error:
02034 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02035 return FALSE;
02036 }
02037
02038 void smlXmlParserFree(SmlXmlParser *parser)
02039 {
02040 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, parser);
02041 smlAssert(parser);
02042
02043 if (parser->reader) {
02044 xmlFreeTextReader(parser->reader);
02045 }
02046 if (parser->data)
02047 smlSafeCFree(&(parser->data));
02048
02049 smlSafeFree((gpointer *)&parser);
02050
02051 smlTrace(TRACE_EXIT, "%s", __func__);
02052 }
02053
02054 SmlBool smlXmlParserGetHeader(SmlXmlParser *parser, SmlHeader **header, SmlCred **cred, SmlError **error)
02055 {
02056 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, header, cred, error);
02057 CHECK_ERROR_REF
02058 smlAssert(parser);
02059 smlAssert(header);
02060 smlAssert(cred);
02061
02062 if (!xmlTextReaderConstName(parser->reader) || strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCHDR) || \
02063 xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
02064
02065 smlErrorSet(error, SML_ERROR_GENERIC, "Wrong starting node for a header");
02066 goto error;
02067 }
02068
02069 parser->version = SML_VERSION_UNKNOWN;
02070
02071 *header = smlTryMalloc0(sizeof(SmlHeader), error);
02072 if (!*header)
02073 goto error;
02074
02075 while (1) {
02076 if (!_smlXmlParserStep(parser)) {
02077 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02078 goto error_free_header;
02079 }
02080
02081 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCHDR) && \
02082 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02083 break;
02084 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
02085 smlErrorSet(error, SML_ERROR_GENERIC,
02086 "The element %s is not a start node in SyncHdr.",
02087 xmlTextReaderConstName(parser->reader));
02088 goto error_free_header;
02089 }
02090
02091 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_VERDTD)) {
02092 if (!_smlSyncHeaderParseDTD(&((*header)->version), parser, error))
02093 goto error_free_header;
02094 parser->version = (*header)->version;
02095 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_VERPROTO)) {
02096 if (!_smlSyncHeaderParseProto(&((*header)->protocol), parser, error))
02097 goto error_free_header;
02098 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SESSIONID)) {
02099 if (!_smlXmlParserGetString(parser, &((*header)->sessionID), SML_ELEMENT_SESSIONID, error))
02100 goto error_free_header;
02101 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MSGID)) {
02102 if (!_smlXmlParserGetID(parser, &((*header)->messageID), SML_ELEMENT_MSGID, error))
02103 goto error_free_header;
02104 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGET)) {
02105 if (!_smlLocationParse(&((*header)->target), parser, error))
02106 goto error_free_header;
02107 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCE)) {
02108 if (!_smlLocationParse(&((*header)->source), parser, error))
02109 goto error_free_header;
02110 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_RESPURI)) {
02111
02112
02113
02114
02115 if ((*header)->responseURI) {
02116 smlTrace(TRACE_ERROR, "%s: There is more than on RespURI.", __func__);
02117 smlSafeCFree(&((*header)->responseURI));
02118 }
02119 if (!_smlXmlParserGetString(parser, &((*header)->responseURI), SML_ELEMENT_RESPURI, error))
02120 goto error_free_header;
02121 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_NORESP)) {
02122
02123 (*header)->noResponse = TRUE;
02124 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_META)) {
02125 if (!_smlMessageParseSynchdrMeta(parser, &((*header)->maxmsgsize), &((*header)->maxobjsize), &((*header)->emi), error))
02126 goto error_free_header;
02127 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CRED)) {
02128 *cred = _smlCredParse(parser, error);
02129 if (!(*cred))
02130 goto error_free_header;
02131 }
02132
02133 else {
02134 smlErrorSet(error, SML_ERROR_GENERIC, "Element %s not supported for SyncHdr.",
02135 (char *)xmlTextReaderConstName(parser->reader));
02136 goto error_free_header;
02137 }
02138 }
02139
02140 if (!(*header)->protocol) {
02141 smlErrorSet(error, SML_ERROR_GENERIC, "No protocol set");
02142 goto error_free_header;
02143 }
02144
02145 if (!(*header)->version) {
02146 smlErrorSet(error, SML_ERROR_GENERIC, "No dtd version set");
02147 goto error_free_header;
02148 }
02149
02150 if (!(*header)->sessionID) {
02151 smlErrorSet(error, SML_ERROR_GENERIC, "No sessionID set");
02152 goto error_free_header;
02153 }
02154
02155 if (!(*header)->target) {
02156 smlErrorSet(error, SML_ERROR_GENERIC, "No target set");
02157 goto error_free_header;
02158 }
02159
02160 if (!(*header)->source) {
02161 smlErrorSet(error, SML_ERROR_GENERIC, "No source set");
02162 goto error_free_header;
02163 }
02164
02165 if (!(*header)->messageID) {
02166 smlErrorSet(error, SML_ERROR_GENERIC, "No msgid set");
02167 goto error_free_header;
02168 }
02169
02170
02171 if (!_smlXmlParserExpectNode(parser, XML_NODE_START, FALSE, SML_ELEMENT_SYNCBODY, error))
02172 goto error_free_header;
02173
02174
02175 if (!xmlTextReaderIsEmptyElement(parser->reader) && !_smlXmlParserStep(parser)) {
02176 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02177 goto error_free_header;
02178 }
02179
02180 smlTrace(TRACE_EXIT, "%s", __func__);
02181 return TRUE;
02182
02183 error_free_header:
02184 smlHeaderFree(*header);
02185 *header = NULL;
02186
02187 if (*cred)
02188 smlCredUnref(*cred);
02189 error:
02190 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02191 return FALSE;
02192 }
02193
02194 SmlBool smlXmlParserGetStatus(SmlXmlParser *parser, SmlStatus **status, SmlError **error)
02195 {
02196 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, status, error);
02197 CHECK_ERROR_REF
02198 smlAssert(parser);
02199 smlAssert(status);
02200
02201 char *locURI = NULL;
02202 SmlItem *item = NULL;
02203
02204
02205 if (smlCommandTypeFromString((char *)xmlTextReaderConstName(parser->reader), error) != SML_COMMAND_TYPE_UNKNOWN && xmlTextReaderNodeType(parser->reader) == XML_NODE_START) {
02206 *status = NULL;
02207 smlTrace(TRACE_EXIT, "%s: Next is command", __func__);
02208 return TRUE;
02209 } else {
02210 smlErrorDeref(error);
02211 }
02212
02213
02214 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FINAL) && (xmlTextReaderNodeType(parser->reader) == XML_NODE_START || xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE)) {
02215 *status = NULL;
02216 smlTrace(TRACE_EXIT, "%s: Next is final", __func__);
02217 return TRUE;
02218 }
02219
02220
02221 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCBODY) &&
02222 (xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE ||
02223 xmlTextReaderIsEmptyElement(parser->reader)
02224 )
02225 ) {
02226 *status = NULL;
02227 smlTrace(TRACE_EXIT, "%s: Next is closing syncbody", __func__);
02228 return TRUE;
02229 }
02230
02231 if (strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_STATUS)) {
02232 smlErrorSet(error, SML_ERROR_GENERIC, "Unexpected element <%s>.",
02233 (char *)xmlTextReaderConstName(parser->reader));
02234 goto error;
02235 }
02236
02237 if (xmlTextReaderIsEmptyElement(parser->reader))
02238 {
02239
02240
02241
02242
02243
02244
02245 _smlXmlParserStep(parser);
02246 smlErrorSet(error, SML_ERROR_GENERIC, "Empty status element");
02247 goto error;
02248 }
02249
02250 if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
02251 smlErrorSet(error, SML_ERROR_GENERIC,
02252 "The element %s is not the start node of Status.",
02253 xmlTextReaderConstName(parser->reader));
02254 goto error;
02255 }
02256
02257 *status = smlStatusNew(SML_ERROR_UNKNOWN, 0, 0, NULL, NULL, SML_COMMAND_TYPE_UNKNOWN, error);
02258 if (!*status)
02259 goto error;
02260
02261 while (1) {
02262 if (!_smlXmlParserStep(parser)) {
02263 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02264 goto error_free_status;
02265 }
02266
02267 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_STATUS) && \
02268 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02269 break;
02270 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
02271 smlErrorSet(error, SML_ERROR_GENERIC,
02272 "The element %s is not a start node in Status.",
02273 xmlTextReaderConstName(parser->reader));
02274 goto error_free_status;
02275 }
02276
02277 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDID)) {
02278
02279 if (!_smlXmlParserExpectNode(parser, XML_NODE_TEXT, FALSE, NULL, error))
02280 goto error_free_status;
02281 if (!_smlXmlParserExpectNode(parser, XML_NODE_CLOSE, FALSE, SML_ELEMENT_CMDID, error))
02282 goto error_free_status;
02283 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MSGREF)) {
02284
02285
02286
02287
02288
02289
02290
02291
02292 if (!_smlXmlParserGetID(parser, &((*status)->msgRef), SML_ELEMENT_MSGREF, error))
02293 goto error_free_status;
02294 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMDREF)) {
02295 if (!_smlXmlParserGetID(parser, &((*status)->cmdRef), SML_ELEMENT_CMDREF, error))
02296 goto error_free_status;
02297 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CMD)) {
02298 char *cmdname = NULL;
02299 if (!_smlXmlParserGetString(parser, &cmdname, SML_ELEMENT_CMD, error))
02300 goto error_free_status;
02301 (*status)->type = smlCommandTypeFromString(cmdname, error);
02302 smlSafeCFree(&cmdname);
02303 if ((*status)->type == SML_COMMAND_TYPE_UNKNOWN)
02304 goto error_free_status;
02305 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATA)) {
02306 if (!_smlXmlParserGetString(parser, &((*status)->data), SML_ELEMENT_DATA, error))
02307 goto error_free_status;
02308 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCEREF)) {
02309 if (!_smlXmlParserGetString(parser, &locURI, SML_ELEMENT_SOURCEREF, error))
02310 goto error_free_status;
02311
02312 (*status)->sourceRef = smlLocationNew(locURI, NULL, error);
02313 smlSafeCFree(&locURI);
02314 if (!(*status)->sourceRef)
02315 goto error_free_status;
02316 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TARGETREF)) {
02317 if (!_smlXmlParserGetString(parser, &locURI, SML_ELEMENT_TARGETREF, error))
02318 goto error_free_status;
02319
02320 (*status)->targetRef = smlLocationNew(locURI, NULL, error);
02321 smlSafeCFree(&locURI);
02322 if (!(*status)->targetRef)
02323 goto error_free_status;
02324 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_ITEM)) {
02325
02326
02327
02328
02329 item = _smlItemParse(parser, NULL, (*status)->type, error);
02330 if (!item)
02331 goto error_free_status;
02332 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CHAL)) {
02333 (*status)->chal = _smlChalParse(parser, error);
02334 if (!(*status)->chal)
02335 goto error_free_status;
02336 } else {
02337 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
02338 goto error;
02339 }
02340 }
02341
02342
02343 if (!_smlXmlParserStep(parser)) {
02344 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02345 goto error_free_status;
02346 }
02347
02348 if (item)
02349 {
02350 if ((*status)->type == SML_COMMAND_TYPE_ALERT) {
02351 (*status)->anchor = item->anchor;
02352 item->anchor = NULL;
02353 } else if ((*status)->type == SML_COMMAND_TYPE_ADD ||
02354 (*status)->type == SML_COMMAND_TYPE_REPLACE ||
02355 (*status)->type == SML_COMMAND_TYPE_DELETE) {
02356
02357
02358
02359
02360 g_warning("Received explicit status for add, delete or replace (%s).", xmlBufferContent(item->buffer));
02361 } else {
02362 smlErrorSet(error, SML_ERROR_GENERIC, "Got wrong item");
02363 smlItemUnref(item);
02364 goto error_free_status;
02365 }
02366 smlItemUnref(item);
02367 }
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380 if ((*status)->type == SML_COMMAND_TYPE_UNKNOWN) {
02381 smlErrorSet(error, SML_ERROR_GENERIC, "No cmd set");
02382 goto error_free_status;
02383 }
02384
02385 smlTrace(TRACE_INTERNAL, "Got status %p with: cmdRef %i, msgRef %i, type %i, data %s", *status, (*status)->cmdRef, (*status)->msgRef, (*status)->type, VA_STRING((*status)->data));
02386
02387 smlTrace(TRACE_EXIT, "%s", __func__);
02388 return TRUE;
02389
02390 error_free_status:
02391 smlStatusUnref(*status);
02392 error:
02393 *status = NULL;
02394 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02395 return FALSE;
02396 }
02397
02398 SmlParserResult smlXmlParserGetCommand(SmlXmlParser *parser, SmlCommand **cmd, SmlError **error)
02399 {
02400 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
02401 CHECK_ERROR_REF
02402 smlAssert(parser);
02403 smlAssert(cmd);
02404 *cmd = NULL;
02405
02406
02407 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FINAL) && (xmlTextReaderNodeType(parser->reader) == XML_NODE_START || xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE)) {
02408 *cmd = NULL;
02409 smlTrace(TRACE_EXIT, "%s: Next is final", __func__);
02410 return SML_PARSER_RESULT_OTHER;
02411 }
02412
02413
02414 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCBODY) &&
02415 (xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE ||
02416 xmlTextReaderIsEmptyElement(parser->reader)
02417 )
02418 ) {
02419 *cmd = NULL;
02420 smlTrace(TRACE_EXIT, "%s: Next is closing syncbody", __func__);
02421 return SML_PARSER_RESULT_OTHER;
02422 }
02423
02424
02425 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_STATUS) && xmlTextReaderNodeType(parser->reader) == XML_NODE_START) {
02426 *cmd = NULL;
02427 smlTrace(TRACE_EXIT, "%s: Next is status", __func__);
02428 return SML_PARSER_RESULT_STATUS;
02429 }
02430
02431 SmlCommandType type = smlCommandTypeFromString((char *)xmlTextReaderConstName(parser->reader), error);
02432 if (!type)
02433 goto error;
02434
02435 SmlParserResult result = SML_PARSER_RESULT_NORMAL;
02436
02437 switch (type) {
02438 case SML_COMMAND_TYPE_ALERT:
02439 if (!_smlAlertParse(parser, cmd, error))
02440 goto error;
02441 break;
02442 case SML_COMMAND_TYPE_PUT:
02443 case SML_COMMAND_TYPE_GET:
02444 if (!_smlCommandAccessParse(parser, cmd, type, error))
02445 goto error;
02446 break;
02447 case SML_COMMAND_TYPE_SYNC:
02448 if (xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02449 if (!_smlXmlParserStep(parser)) {
02450 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02451 goto error_free_cmd;
02452 }
02453
02454 smlTrace(TRACE_EXIT, "%s: SML_PARSER_RESULT_CLOSE", __func__);
02455 return SML_PARSER_RESULT_CLOSE;
02456 } else {
02457 if (!_smlCommandSyncParse(parser, cmd, error))
02458 goto error;
02459
02460 result = SML_PARSER_RESULT_OPEN;
02461 }
02462 break;
02463 case SML_COMMAND_TYPE_MAP:
02464 if (!_smlCommandMapParse(parser, cmd, error))
02465 goto error;
02466 break;
02467 case SML_COMMAND_TYPE_ADD:
02468 if (!_smlChangeParse(parser, cmd, SML_COMMAND_TYPE_ADD, SML_ELEMENT_ADD, error))
02469 goto error;
02470 break;
02471 case SML_COMMAND_TYPE_REPLACE:
02472 if (!_smlChangeParse(parser, cmd, SML_COMMAND_TYPE_REPLACE, SML_ELEMENT_REPLACE, error))
02473 goto error;
02474 break;
02475 case SML_COMMAND_TYPE_DELETE:
02476 if (!_smlChangeParse(parser, cmd, SML_COMMAND_TYPE_DELETE, SML_ELEMENT_DELETE, error))
02477 goto error;
02478 break;
02479 case SML_COMMAND_TYPE_RESULTS:
02480 if (!_smlResultsParse(parser, cmd, error))
02481 goto error;
02482 break;
02483 default:
02484 smlErrorSet(error, SML_ERROR_GENERIC, "Unsupported command type");
02485 goto error;
02486 }
02487
02488 if (!(*cmd)->cmdID) {
02489 smlErrorSet(error, SML_ERROR_GENERIC, "No cmdid set");
02490 goto error_free_cmd;
02491 }
02492
02493 parser->got_command = TRUE;
02494
02495 smlTrace(TRACE_EXIT, "%s: %i", __func__, result);
02496 return result;
02497
02498 error_free_cmd:
02499 if (*cmd)
02500 smlCommandUnref(*cmd);
02501 error:
02502 *cmd = NULL;
02503 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02504 return SML_PARSER_RESULT_ERROR;
02505 }
02506
02507 SmlXmlParser *smlXmlParserNew(SmlParserFunctions *functions, SmlError **error)
02508 {
02509 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, functions,error);
02510 CHECK_ERROR_REF
02511 smlAssert(functions);
02512
02513 SmlXmlParser *parser = smlTryMalloc0(sizeof(SmlXmlParser), error);
02514 if (!parser)
02515 goto error;
02516
02517 functions->start = (SmlParserStartFunction)smlXmlParserStart;
02518 functions->free = (SmlParserFreeFunction)smlXmlParserFree;
02519 functions->end = (SmlParserEndFunction)smlXmlParserEnd;
02520 functions->get_header = (SmlParserHeaderFunction)smlXmlParserGetHeader;
02521 functions->get_cmd = (SmlParserCommandFunction)smlXmlParserGetCommand;
02522 functions->get_status = (SmlParserStatusFunction)smlXmlParserGetStatus;
02523
02524 smlTrace(TRACE_EXIT, "%s: %p", __func__, parser);
02525 return parser;
02526
02527 error:
02528 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02529 return NULL;
02530 }
02531
02532 static SmlBool _smlXmlDevInfDataStoreParseDSMem(SmlXmlParser *parser, SmlDevInfDataStore *datastore, SmlError **error)
02533 {
02534 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, datastore, error);
02535 CHECK_ERROR_REF
02536 smlAssert(parser);
02537 smlAssert(datastore);
02538
02539 if (xmlTextReaderIsEmptyElement(parser->reader)) {
02540
02541 smlTrace(TRACE_EXIT, "%s - empty DSMem", __func__);
02542 return TRUE;
02543 }
02544
02545 while (1) {
02546 if (!_smlXmlParserStep(parser)) {
02547 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02548 goto error;
02549 }
02550
02551 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DSMEM) && \
02552 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02553 break;
02554 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
02555 smlErrorSet(error, SML_ERROR_GENERIC,
02556 "The element %s is not a start node in DSMem.",
02557 xmlTextReaderConstName(parser->reader));
02558 goto error;
02559 }
02560
02561 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAXID)) {
02562 if (!_smlXmlParserGetID(parser, &(datastore->maxid), SML_ELEMENT_MAXID, error))
02563 goto error;
02564 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SHAREDMEM)) {
02565 datastore->sharedMem = TRUE;
02566 if (!_smlXmlParserStep(parser)) {
02567 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02568 goto error;
02569 }
02570
02571 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SHAREDMEM) && \
02572 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02573 if (!_smlXmlParserStep(parser)) {
02574 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes2");
02575 goto error;
02576 }
02577 }
02578 continue;
02579 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAXMEM)) {
02580 if (!_smlXmlParserGetID(parser, &(datastore->maxmem), SML_ELEMENT_MAXMEM, error))
02581 goto error;
02582 } else {
02583 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
02584 goto error;
02585 }
02586 }
02587
02588 smlTrace(TRACE_EXIT, "%s", __func__);
02589 return TRUE;
02590
02591 error:
02592 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02593 return FALSE;
02594 }
02595
02596 static SmlBool _smlXmlDevInfDataStoreParseSyncCap(SmlXmlParser *parser, SmlDevInfDataStore *datastore, SmlError **error)
02597 {
02598 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, datastore, error);
02599 CHECK_ERROR_REF
02600 smlAssert(parser);
02601 smlAssert(datastore);
02602
02603 while (1) {
02604 if (!_smlXmlParserStep(parser)) {
02605 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02606 goto error;
02607 }
02608
02609 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCCAP) && \
02610 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02611 break;
02612 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
02613 smlErrorSet(error, SML_ERROR_GENERIC,
02614 "The element %s is not a start node in SyncCap.",
02615 xmlTextReaderConstName(parser->reader));
02616 goto error;
02617 }
02618
02619 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCTYPE)) {
02620 unsigned int id = 0;
02621 if (!_smlXmlParserGetID(parser, &id, SML_ELEMENT_SYNCTYPE, error))
02622 goto error;
02623 id = 1 << (id - 1);
02624 SmlDevInfSyncCap synccap = smlDevInfSyncCapConvert(id, error);
02625 if (synccap == SML_DEVINF_SYNCTYPE_UNKNOWN &&
02626 error != NULL)
02627 goto error;
02628
02629 if (synccap != SML_DEVINF_SYNCTYPE_UNKNOWN)
02630 smlDevInfDataStoreSetSyncCap(datastore, synccap, TRUE);
02631 } else {
02632 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
02633 goto error;
02634 }
02635 }
02636
02637 smlTrace(TRACE_EXIT, "%s", __func__);
02638 return TRUE;
02639
02640 error:
02641 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02642 return FALSE;
02643 }
02644
02645 static SmlBool _smlXmlDevInfDataStoreParseCTCap11(SmlXmlParser *parser, SmlDevInf *devinf, SmlError **error)
02646 {
02647 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, devinf, error);
02648 CHECK_ERROR_REF
02649 smlAssert(parser);
02650 smlAssert(devinf);
02651
02652
02653
02654
02655 if (!_smlXmlParserStep(parser)) {
02656 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02657 goto error;
02658 }
02659
02660 SmlDevInfCTCap *ctcap = NULL;
02661 SmlDevInfProperty *property = NULL;
02662 SmlDevInfPropParam *param = NULL;
02663 char *value = NULL;
02664 while (1) {
02665
02666 const char *elem_name;
02667 elem_name = (const char*)xmlTextReaderConstName(parser->reader);
02668
02669 smlTrace(TRACE_INTERNAL, "read: %s\n", elem_name);
02670 if (!strcmp(elem_name, SML_ELEMENT_CTCAP) &&
02671 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02672
02673 break;
02674 }
02675
02676 if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START)
02677 {
02678 smlErrorSet(error, SML_ERROR_GENERIC,
02679 "The element %s is not a start node in CTCap.",
02680 xmlTextReaderConstName(parser->reader));
02681 goto error;
02682 }
02683
02684
02685 SmlDevInfCTCapType type;
02686 type = smlDevInfCTCapTypeFromString(elem_name, error);
02687 value = NULL;
02688 if (type != SML_DEVINF_CTCAP_UNKNOWN)
02689 {
02690 _smlXmlParserGetString(parser, &value, elem_name, error);
02691 }
02692
02693
02694 switch(type)
02695 {
02696 case SML_DEVINF_CTCAP_CTTYPE:
02697
02698 if (ctcap != NULL)
02699 {
02700 if (property != NULL)
02701 {
02702 if (param != NULL)
02703 {
02704 smlDevInfPropertyAddPropParam(property, param);
02705 param = NULL;
02706 }
02707 smlDevInfCTCapAddProperty(ctcap, property);
02708 property = NULL;
02709 }
02710 smlDevInfAppendCTCap(devinf, ctcap);
02711 ctcap = NULL;
02712 }
02713 ctcap = smlDevInfNewCTCap(error);
02714 if (!ctcap)
02715 goto error;
02716 smlDevInfCTCapSetCTType(ctcap, value);
02717 break;
02718 case SML_DEVINF_CTCAP_VERCT:
02719 if (ctcap == NULL)
02720 goto error;
02721 smlDevInfCTCapSetVerCT(ctcap, value);
02722 break;
02723 case SML_DEVINF_CTCAP_PROPNAME:
02724
02725 if (ctcap == NULL)
02726 goto error;
02727 if (property != NULL)
02728 {
02729 if (param != NULL)
02730 {
02731 smlDevInfPropertyAddPropParam(property, param);
02732 param = NULL;
02733 }
02734 smlDevInfCTCapAddProperty(ctcap, property);
02735 property = NULL;
02736 }
02737 property = smlDevInfNewProperty(error);
02738 if (!property)
02739 goto error;
02740 smlDevInfPropertySetPropName(property, value);
02741 break;
02742 case SML_DEVINF_CTCAP_DATATYPE:
02743 if (property == NULL)
02744 goto error;
02745 if (param != NULL)
02746 smlDevInfPropParamSetDataType(param, value);
02747 else
02748 smlDevInfPropertySetDataType(property, value);
02749 break;
02750 case SML_DEVINF_CTCAP_MAXOCCUR:
02751 if (property == NULL)
02752 goto error;
02753 smlDevInfPropertySetMaxOccur(property, atoi(value));
02754 break;
02755 case SML_DEVINF_CTCAP_MAXSIZE:
02756 if (property == NULL)
02757 goto error;
02758 smlDevInfPropertySetMaxSize(property, atoi(value));
02759 break;
02760 case SML_DEVINF_CTCAP_NOTRUNCATE:
02761 if (property == NULL)
02762 goto error;
02763 smlDevInfPropertySetNoTruncate(property);
02764 break;
02765 case SML_DEVINF_CTCAP_DISPLAYNAME:
02766 if (property == NULL)
02767 goto error;
02768 if (param != NULL)
02769 smlDevInfPropParamSetDisplayName(param, value);
02770 else
02771 smlDevInfPropertySetDisplayName(property, value);
02772 break;
02773 case SML_DEVINF_CTCAP_VALENUM:
02774 if (property == NULL)
02775 goto error;
02776 if (param != NULL)
02777 smlDevInfPropParamAddValEnum(param, value);
02778 else
02779 smlDevInfPropertyAddValEnum(property, value);
02780 break;
02781 case SML_DEVINF_CTCAP_PARAMNAME:
02782 if (property == NULL)
02783 goto error;
02784 if (param != NULL)
02785 {
02786 smlDevInfPropertyAddPropParam(property, param);
02787 param = NULL;
02788 }
02789 param = smlDevInfNewPropParam(error);
02790 if (!param)
02791 goto error;
02792 smlDevInfPropParamSetParamName(param, value);
02793 break;
02794 case SML_DEVINF_CTCAP_SIZE:
02795 smlDevInfPropertySetPropSize(property, atoi(value));
02796 break;
02797 default:
02798 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown CTCapType: %s", elem_name);
02799 goto error;
02800 }
02801 smlSafeCFree(&value);
02802
02803 if (!_smlXmlParserStep(parser)) {
02804 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02805 goto error;
02806 }
02807 }
02808 if (param != NULL)
02809 smlDevInfPropertyAddPropParam(property, param);
02810 if (property != NULL)
02811 smlDevInfCTCapAddProperty(ctcap, property);
02812 if (ctcap != NULL)
02813 smlDevInfAppendCTCap(devinf, ctcap);
02814
02815 smlTrace(TRACE_EXIT, "%s", __func__);
02816 return TRUE;
02817
02818 error:
02819 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02820 if (value != NULL)
02821 smlSafeCFree(&value);
02822 return FALSE;
02823 }
02824
02825 static SmlDevInfPropParam *_smlXmlDevInfDataStoreParseCTCap12PropParam(SmlXmlParser *parser, SmlError **error)
02826 {
02827 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, error);
02828 CHECK_ERROR_REF
02829 smlAssert(parser);
02830
02831 if (!_smlXmlParserStep(parser)) {
02832 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02833 goto error;
02834 }
02835
02836 SmlDevInfPropParam *param = smlDevInfNewPropParam(error);
02837 if (!param)
02838 goto error;
02839
02840 char *value = NULL;
02841 while (1) {
02842
02843 const char *elem_name;
02844 elem_name = (const char*)xmlTextReaderConstName(parser->reader);
02845
02846 smlTrace(TRACE_INTERNAL, "read: %s\n", elem_name);
02847 if (!strcmp(elem_name, SML_ELEMENT_PROPPARAM) &&
02848 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02849
02850 break;
02851 }
02852
02853 if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START)
02854 {
02855 smlErrorSet(error, SML_ERROR_GENERIC,
02856 "The element %s is not a start node in PropParam.",
02857 xmlTextReaderConstName(parser->reader));
02858 goto error;
02859 }
02860
02861
02862 SmlDevInfCTCapType type;
02863 type = smlDevInfCTCapTypeFromString(elem_name, error);
02864 value = NULL;
02865 if (type != SML_DEVINF_CTCAP_UNKNOWN)
02866 {
02867 _smlXmlParserGetString(parser, &value, elem_name, error);
02868 }
02869
02870
02871 switch(type)
02872 {
02873 case SML_DEVINF_CTCAP_PARAMNAME:
02874 smlDevInfPropParamSetParamName(param, value);
02875 break;
02876 case SML_DEVINF_CTCAP_DATATYPE:
02877 smlDevInfPropParamSetDataType(param, value);
02878 break;
02879 case SML_DEVINF_CTCAP_DISPLAYNAME:
02880 smlDevInfPropParamSetDisplayName(param, value);
02881 break;
02882 case SML_DEVINF_CTCAP_VALENUM:
02883 smlDevInfPropParamAddValEnum(param, value);
02884 break;
02885 default:
02886 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown CTCapType for PropParam: %s", elem_name);
02887 goto error;
02888 }
02889 smlSafeCFree(&value);
02890
02891 if (!_smlXmlParserStep(parser)) {
02892 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02893 goto error;
02894 }
02895 }
02896
02897 smlTrace(TRACE_EXIT, "%s", __func__);
02898 return param;
02899
02900 error:
02901 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
02902 if (value != NULL)
02903 smlSafeCFree(&value);
02904 return NULL;
02905 }
02906
02907 static SmlDevInfProperty *_smlXmlDevInfDataStoreParseCTCap12Property(SmlXmlParser *parser, SmlError **error)
02908 {
02909 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, error);
02910 CHECK_ERROR_REF
02911 smlAssert(parser);
02912
02913 if (!_smlXmlParserStep(parser)) {
02914 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02915 goto error;
02916 }
02917
02918 SmlDevInfProperty *property = smlDevInfNewProperty(error);
02919 if (!property)
02920 goto error;
02921
02922 SmlDevInfPropParam *param;
02923 char *value = NULL;
02924 while (1) {
02925
02926 const char *elem_name;
02927 elem_name = (const char*)xmlTextReaderConstName(parser->reader);
02928
02929 smlTrace(TRACE_INTERNAL, "read: %s\n", elem_name);
02930 if (!strcmp(elem_name, SML_ELEMENT_PROPERTY) &&
02931 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
02932
02933 break;
02934 }
02935
02936 if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START)
02937 {
02938 smlErrorSet(error, SML_ERROR_GENERIC,
02939 "The element %s is not a start node in Property.",
02940 xmlTextReaderConstName(parser->reader));
02941 goto error;
02942 }
02943
02944
02945 SmlDevInfCTCapType type;
02946 type = smlDevInfCTCapTypeFromString(elem_name, error);
02947 value = NULL;
02948 if (type != SML_DEVINF_CTCAP_UNKNOWN &&
02949 type != SML_DEVINF_CTCAP_PROPPARAM)
02950 {
02951 _smlXmlParserGetString(parser, &value, elem_name, error);
02952 }
02953
02954
02955 switch(type)
02956 {
02957 case SML_DEVINF_CTCAP_PROPNAME:
02958 smlDevInfPropertySetPropName(property, value);
02959 break;
02960 case SML_DEVINF_CTCAP_DATATYPE:
02961 smlDevInfPropertySetDataType(property, value);
02962 break;
02963 case SML_DEVINF_CTCAP_MAXOCCUR:
02964 smlDevInfPropertySetMaxOccur(property, atoi(value));
02965 break;
02966 case SML_DEVINF_CTCAP_MAXSIZE:
02967 smlDevInfPropertySetMaxSize(property, atoi(value));
02968 break;
02969 case SML_DEVINF_CTCAP_NOTRUNCATE:
02970 smlDevInfPropertySetNoTruncate(property);
02971 break;
02972 case SML_DEVINF_CTCAP_DISPLAYNAME:
02973 smlDevInfPropertySetDisplayName(property, value);
02974 break;
02975 case SML_DEVINF_CTCAP_VALENUM:
02976 smlDevInfPropertyAddValEnum(property, value);
02977 break;
02978 case SML_DEVINF_CTCAP_PROPPARAM:
02979 param = _smlXmlDevInfDataStoreParseCTCap12PropParam(parser, error);
02980 if (!param)
02981 goto error;
02982 smlDevInfPropertyAddPropParam(property, param);
02983 break;
02984 case SML_DEVINF_CTCAP_SIZE:
02985 smlDevInfPropertySetPropSize(property, atoi(value));
02986 break;
02987 default:
02988 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown CTCapType for Property: %s", elem_name);
02989 goto error;
02990 }
02991 if (value) smlSafeCFree(&value);
02992
02993 if (!_smlXmlParserStep(parser)) {
02994 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
02995 goto error;
02996 }
02997 }
02998
02999 smlTrace(TRACE_EXIT, "%s", __func__);
03000 return property;
03001
03002 error:
03003 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
03004 if (value != NULL)
03005 smlSafeCFree(&value);
03006 return NULL;
03007 }
03008
03009 static SmlBool _smlXmlDevInfDataStoreParseCTCap12(SmlXmlParser *parser, SmlDevInf *devinf, SmlError **error)
03010 {
03011 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, devinf, error);
03012 CHECK_ERROR_REF
03013 smlAssert(parser);
03014 smlAssert(devinf);
03015
03016
03017
03018
03019 if (!_smlXmlParserStep(parser)) {
03020 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03021 goto error;
03022 }
03023
03024 SmlDevInfCTCap *ctcap = smlDevInfNewCTCap(error);
03025 if (!ctcap)
03026 goto error;
03027
03028 SmlDevInfProperty *property;
03029 char *value = NULL;
03030 while (1) {
03031
03032 const char *elem_name;
03033 elem_name = (const char*)xmlTextReaderConstName(parser->reader);
03034
03035 smlTrace(TRACE_INTERNAL, "read: %s\n", elem_name);
03036 if (!strcmp(elem_name, SML_ELEMENT_CTCAP) &&
03037 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03038
03039 break;
03040 }
03041
03042 if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START)
03043 {
03044 smlErrorSet(error, SML_ERROR_GENERIC,
03045 "The element %s is not a start node in CtCap.",
03046 xmlTextReaderConstName(parser->reader));
03047 goto error;
03048 }
03049
03050
03051 SmlDevInfCTCapType type;
03052 type = smlDevInfCTCapTypeFromString(elem_name, error);
03053 value = NULL;
03054 if (type != SML_DEVINF_CTCAP_UNKNOWN &&
03055 type != SML_DEVINF_CTCAP_PROPERTY)
03056 {
03057 _smlXmlParserGetString(parser, &value, elem_name, error);
03058 }
03059
03060
03061 switch(type)
03062 {
03063 case SML_DEVINF_CTCAP_CTTYPE:
03064 smlDevInfCTCapSetCTType(ctcap, value);
03065 break;
03066 case SML_DEVINF_CTCAP_VERCT:
03067 smlDevInfCTCapSetVerCT(ctcap, value);
03068 break;
03069 case SML_DEVINF_CTCAP_PROPERTY:
03070 property = _smlXmlDevInfDataStoreParseCTCap12Property(parser, error);
03071 if (!property)
03072 goto error;
03073 smlDevInfCTCapAddProperty(ctcap, property);
03074 break;
03075 default:
03076 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown CTCapType for CTCap: %s", elem_name);
03077 goto error;
03078 }
03079 if (value) smlSafeCFree(&value);
03080
03081 if (!_smlXmlParserStep(parser)) {
03082 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03083 goto error;
03084 }
03085 }
03086 smlDevInfAppendCTCap(devinf, ctcap);
03087
03088 smlTrace(TRACE_EXIT, "%s", __func__);
03089 return TRUE;
03090
03091 error:
03092 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
03093 if (value != NULL)
03094 smlSafeCFree(&value);
03095 return FALSE;
03096 }
03097
03098 static SmlBool _smlXmlDevInfDataStoreParseCTCap(SmlXmlParser *parser, SmlDevInf *devinf, SmlError **error)
03099 {
03100 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, devinf, error);
03101 CHECK_ERROR_REF
03102 smlAssert(parser);
03103 smlAssert(devinf);
03104
03105
03106
03107
03108
03109
03110
03111 SmlBool ret;
03112 if (devinf->version == SML_DEVINF_VERSION_12)
03113 ret = _smlXmlDevInfDataStoreParseCTCap12(parser, devinf, error);
03114 else
03115 ret = _smlXmlDevInfDataStoreParseCTCap11(parser, devinf, error);
03116
03117 smlTrace(TRACE_EXIT, "%s (%d)", __func__, ret);
03118 return ret;
03119 }
03120
03121 static SmlBool _smlXmlDevInfDataStoreParseRxTx(SmlXmlParser *parser, const char *element, char **cttype, char **version, SmlError **error)
03122 {
03123 smlTrace(TRACE_ENTRY, "%s(%p, %s, %p, %p, %p)", __func__, parser, VA_STRING(element), cttype, version, error);
03124 CHECK_ERROR_REF
03125 smlAssert(parser);
03126 smlAssert(element);
03127 smlAssert(cttype);
03128
03129 if (!_smlXmlParserStep(parser)) {
03130 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03131 goto error;
03132 }
03133
03134 while (1) {
03135 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), element) && \
03136 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03137 break;
03138 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
03139 smlErrorSet(error, SML_ERROR_GENERIC,
03140 "The element %s is not a start node in %s.",
03141 xmlTextReaderConstName(parser->reader), element);
03142 goto error;
03143 }
03144
03145 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CTTYPE)) {
03146 if (!_smlXmlParserGetString(parser, cttype, SML_ELEMENT_CTTYPE, error))
03147 goto error;
03148 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_VERCT)) {
03149
03150
03151 if (!_smlXmlParserStep(parser)) {
03152 smlErrorSet(error, SML_ERROR_GENERIC, "No node at all");
03153 goto error;
03154 }
03155
03156 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_VERCT) && \
03157 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03158 *version = g_strdup("");
03159 } else if (xmlTextReaderNodeType(parser->reader) == XML_NODE_TEXT) {
03160 *version = g_strstrip(g_strdup((char *)xmlTextReaderConstValue(parser->reader)));
03161
03162 if (!_smlXmlParserExpectNode(parser, XML_NODE_CLOSE, FALSE, SML_ELEMENT_VERCT, error))
03163 goto error;
03164 } else {
03165 *version = g_strdup("");
03166 continue;
03167 }
03168 } else {
03169 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node");
03170 goto error;
03171 }
03172
03173 if (!_smlXmlParserStep(parser)) {
03174 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03175 goto error;
03176 }
03177 }
03178
03179 smlTrace(TRACE_EXIT, "%s", __func__);
03180 return TRUE;
03181
03182 error:
03183 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
03184 return FALSE;
03185 }
03186
03187 static SmlBool _smlXmlDevInfDataStoreParse(SmlXmlParser *parser, SmlDevInf *devinf, SmlError **error)
03188 {
03189 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, devinf, error);
03190 CHECK_ERROR_REF
03191 smlAssert(devinf);
03192 smlAssert(parser);
03193
03194 SmlDevInfDataStore *datastore = smlTryMalloc0(sizeof(SmlDevInfDataStore), error);
03195 if (!datastore)
03196 goto error;
03197 datastore->refCount = 1;
03198 datastore->rxPrefContentType = NULL;
03199 datastore->txPrefContentType = NULL;
03200
03201 if (!_smlXmlParserStep(parser)) {
03202 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03203 goto error_free_datastore;
03204 }
03205
03206 while (1) {
03207
03208 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATASTORE) && \
03209 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03210 break;
03211 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
03212 smlErrorSet(error, SML_ERROR_GENERIC,
03213 "The element %s is not a start node in Datastore.",
03214 xmlTextReaderConstName(parser->reader));
03215 goto error_free_datastore;
03216 }
03217
03218 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SOURCEREF)) {
03219 if (!_smlXmlParserGetString(parser, &(datastore->sourceref), SML_ELEMENT_SOURCEREF, error))
03220 goto error_free_datastore;
03221 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DISPLAYNAME)) {
03222 if (!_smlXmlParserGetString(parser, &(datastore->displayname), SML_ELEMENT_DISPLAYNAME, error))
03223 goto error_free_datastore;
03224 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAXGUIDSIZE)) {
03225 if (!_smlXmlParserGetID(parser, &(datastore->maxGUIDSize), SML_ELEMENT_MAXGUIDSIZE, error))
03226 goto error_free_datastore;
03227 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_RXPREF)) {
03228 if (!_smlXmlDevInfDataStoreParseRxTx(parser, SML_ELEMENT_RXPREF, &(datastore->rxPrefContentType), &(datastore->rxPrefVersion), error))
03229 goto error_free_datastore;
03230 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_RX)) {
03231 char *cttype = NULL;
03232 char *verct = NULL;
03233 if (!_smlXmlDevInfDataStoreParseRxTx(parser, SML_ELEMENT_RX, &cttype, &verct, error))
03234 goto error_free_datastore;
03235 SmlDevInfContentType *ct = smlDevInfNewContentType(cttype, verct, error);
03236 smlSafeCFree(&cttype);
03237 if (verct)
03238 smlSafeCFree(&verct);
03239 if (!ct)
03240 goto error_free_datastore;
03241 smlDevInfDataStoreAddRx(datastore, ct);
03242 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TXPREF)) {
03243 if (!_smlXmlDevInfDataStoreParseRxTx(parser, SML_ELEMENT_TXPREF, &(datastore->txPrefContentType), &(datastore->txPrefVersion), error))
03244 goto error_free_datastore;
03245 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_TX)) {
03246 char *cttype = NULL;
03247 char *verct = NULL;
03248 if (!_smlXmlDevInfDataStoreParseRxTx(parser, SML_ELEMENT_TX, &cttype, &verct, error))
03249 goto error_free_datastore;
03250 SmlDevInfContentType *ct = smlDevInfNewContentType(cttype, verct, error);
03251 smlSafeCFree(&cttype);
03252 if (verct)
03253 smlSafeCFree(&verct);
03254 if (!ct)
03255 goto error_free_datastore;
03256 smlDevInfDataStoreAddTx(datastore, ct);
03257 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CTCAP)) {
03258 if (!_smlXmlDevInfDataStoreParseCTCap(parser, devinf, error))
03259 goto error_free_datastore;
03260 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SYNCCAP)) {
03261 if (!_smlXmlDevInfDataStoreParseSyncCap(parser, datastore, error))
03262 goto error_free_datastore;
03263 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DSMEM)) {
03264 if (!_smlXmlDevInfDataStoreParseDSMem(parser, datastore, error))
03265 goto error_free_datastore;
03266 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SUPPORT_HIERARCHICAL_SYNC)) {
03267 if (devinf->version < SML_DEVINF_VERSION_12) {
03268 smlErrorSet(error, SML_ERROR_GENERIC, "SupportHierarchicalSync is only supported in OMA DS 1.2 DevInf and later.");
03269 goto error;
03270 }
03271 datastore->supportsHierarchicalSync = TRUE;
03272 if (!xmlTextReaderIsEmptyElement(parser->reader)) {
03273 if (!_smlXmlParserStep(parser)) {
03274 smlErrorSet(error, SML_ERROR_GENERIC, "The closing element of %s is missing.", SML_ELEMENT_SUPPORT_HIERARCHICAL_SYNC);
03275 goto error;
03276 }
03277 }
03278 } else {
03279 smlErrorSet(error, SML_ERROR_GENERIC, "A DataStore within DevInf includes the unsupported element %s.", (char *)xmlTextReaderConstName(parser->reader));
03280 goto error_free_datastore;
03281 }
03282
03283 if (!_smlXmlParserStep(parser)) {
03284 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03285 goto error_free_datastore;
03286 }
03287 }
03288
03289 smlDevInfAddDataStore(devinf, datastore);
03290
03291 smlTrace(TRACE_EXIT, "%s", __func__);
03292 return TRUE;
03293
03294 error_free_datastore:
03295 smlDevInfDataStoreUnref(datastore);
03296 error:
03297 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
03298 return FALSE;
03299 }
03300
03301 SmlDevInf *smlXmlDevInfParse(const char *data, unsigned int size, SmlError **error)
03302 {
03303 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data, size, error);
03304 CHECK_ERROR_REF
03305 smlAssert(data);
03306 smlAssert(size);
03307 SmlDevInf *devinf = NULL;
03308
03309
03310 char *debugstr = smlPrintBinary(data, size);
03311 smlTrace(TRACE_INTERNAL, "Xml devinf input: %s", debugstr);
03312 smlSafeCFree(&debugstr);
03313
03314 SmlXmlParser *parser = smlTryMalloc0(sizeof(SmlXmlParser), error);
03315 if (!parser)
03316 goto error;
03317
03318
03319 parser->reader = xmlReaderForMemory(data, size, "/", NULL, XML_PARSE_NONET | XML_PARSE_NOERROR | XML_PARSE_NOWARNING | XML_PARSE_NOCDATA | XML_PARSER_SUBST_ENTITIES);
03320 if (!parser->reader) {
03321 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to create new reader");
03322 goto error;
03323 }
03324 xmlSubstituteEntitiesDefault(1);
03325
03326
03327 if (!_smlXmlParserExpectNode(parser, XML_NODE_START, FALSE, SML_ELEMENT_DEVINF, error))
03328 goto error;
03329
03330 devinf = smlTryMalloc0(sizeof(SmlDevInf), error);
03331 if (!devinf)
03332 goto error;
03333
03334 smlDevInfRef(devinf);
03335
03336 if (!_smlXmlParserStep(parser)) {
03337 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03338 goto error;
03339 }
03340
03341 while (1) {
03342 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DEVINF) && \
03343 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03344 break;
03345 } else if (xmlTextReaderNodeType(parser->reader) != XML_NODE_START) {
03346 smlErrorSet(error, SML_ERROR_GENERIC,
03347 "The element %s is not a start node in DevInf.",
03348 xmlTextReaderConstName(parser->reader));
03349 goto error;
03350 }
03351
03352
03353 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_VERDTD)) {
03354 char *verdtd = NULL;
03355 if (!_smlXmlParserGetString(parser, &verdtd, SML_ELEMENT_VERDTD, error))
03356 goto error;
03357
03358 if (verdtd && !strcmp(verdtd, "1.1"))
03359 devinf->version = SML_DEVINF_VERSION_11;
03360 else if (verdtd && !strcmp(verdtd, "1.0"))
03361 devinf->version = SML_DEVINF_VERSION_10;
03362 else if (verdtd && !strcmp(verdtd, "1.2"))
03363 devinf->version = SML_DEVINF_VERSION_12;
03364 else {
03365 smlSafeCFree(&verdtd);
03366 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown devinf version");
03367 goto error;
03368 }
03369 smlSafeCFree(&verdtd);
03370 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MAN)) {
03371 if (!_smlXmlParserGetString(parser, &(devinf->manufacturer), SML_ELEMENT_MAN, error))
03372 goto error;
03373 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_MOD)) {
03374 if (!_smlXmlParserGetString(parser, &(devinf->model), SML_ELEMENT_MOD, error))
03375 goto error;
03376 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_OEM)) {
03377 if (!_smlXmlParserGetString(parser, &(devinf->oem), SML_ELEMENT_OEM, error))
03378 goto error;
03379 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_FWV)) {
03380 if (!_smlXmlParserGetString(parser, &(devinf->firmwareVersion), SML_ELEMENT_FWV, error))
03381 goto error;
03382 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SWV)) {
03383 if (!_smlXmlParserGetString(parser, &(devinf->softwareVersion), SML_ELEMENT_SWV, error))
03384 goto error;
03385 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_HWV)) {
03386 if (!_smlXmlParserGetString(parser, &(devinf->hardwareVersion), SML_ELEMENT_HWV, error))
03387 goto error;
03388 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DEVID)) {
03389 if (!_smlXmlParserGetString(parser, &(devinf->devid), SML_ELEMENT_DEVID, error))
03390 goto error;
03391 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DEVTYPE)) {
03392 char *devtype = NULL;
03393 if (!_smlXmlParserGetString(parser, &devtype, SML_ELEMENT_DEVTYPE, error))
03394 goto error;
03395
03396 devinf->devtyp = smlDevInfDevTypeFromString(devtype, error);
03397 smlSafeCFree(&devtype);
03398
03399 if (devinf->devtyp == SML_DEVINF_DEVTYPE_UNKNOWN)
03400 goto error;
03401 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_UTC)) {
03402 if (devinf->version == SML_DEVINF_VERSION_10) {
03403 smlErrorSet(error, SML_ERROR_GENERIC, "Devinf 1.0 does not allow UTC");
03404 goto error;
03405 }
03406
03407 devinf->supportsUTC = TRUE;
03408 if (!_smlXmlParserStep(parser)) {
03409 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03410 goto error;
03411 }
03412
03413 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_UTC) && \
03414 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03415 if (!_smlXmlParserStep(parser)) {
03416 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes2");
03417 goto error;
03418 }
03419 }
03420 continue;
03421 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SUPPORTLARGEOBJS)) {
03422 if (devinf->version == SML_DEVINF_VERSION_10) {
03423 smlErrorSet(error, SML_ERROR_GENERIC, "Devinf 1.0 does not allow large objects");
03424 goto error;
03425 }
03426
03427 devinf->supportsLargeObjs = TRUE;
03428 if (!_smlXmlParserStep(parser)) {
03429 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03430 goto error;
03431 }
03432
03433 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SUPPORTLARGEOBJS) && \
03434 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03435 if (!_smlXmlParserStep(parser)) {
03436 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes2");
03437 goto error;
03438 }
03439 }
03440 continue;
03441 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SUPPORTNUMBEROFCHANGES)) {
03442 if (devinf->version == SML_DEVINF_VERSION_10) {
03443 smlErrorSet(error, SML_ERROR_GENERIC, "Devinf 1.0 does not allow number of changes");
03444 goto error;
03445 }
03446
03447 devinf->supportsNumberOfChanges = TRUE;
03448 if (!_smlXmlParserStep(parser)) {
03449 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03450 goto error;
03451 }
03452
03453 if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_SUPPORTNUMBEROFCHANGES) && \
03454 xmlTextReaderNodeType(parser->reader) == XML_NODE_CLOSE) {
03455 if (!_smlXmlParserStep(parser)) {
03456 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes2");
03457 goto error;
03458 }
03459 }
03460 continue;
03461 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_DATASTORE)) {
03462 if (!_smlXmlDevInfDataStoreParse(parser, devinf, error))
03463 goto error;
03464 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_CTCAP)) {
03465
03466
03467
03468 if (!_smlXmlDevInfDataStoreParseCTCap(parser, devinf, error))
03469 goto error;
03470 } else if (!strcmp((char *)xmlTextReaderConstName(parser->reader), SML_ELEMENT_EXT)) {
03471
03472 smlTrace(TRACE_INTERNAL, "%s: Skipping ext node");
03473 if (!_smlXmlSkipNode(parser)) {
03474 smlErrorSet(error, SML_ERROR_GENERIC, "Unable to skip ext node");
03475 goto error;
03476 }
03477 continue;
03478 } else {
03479 smlErrorSet(error, SML_ERROR_GENERIC, "wrong initial node: %s", (char *)xmlTextReaderConstName(parser->reader));
03480 goto error;
03481 }
03482
03483 if (!_smlXmlParserStep(parser)) {
03484 smlErrorSet(error, SML_ERROR_GENERIC, "Missing nodes");
03485 goto error;
03486 }
03487 }
03488
03489 xmlFreeTextReader(parser->reader);
03490 parser->reader = NULL;
03491 smlSafeFree((gpointer *)&parser);
03492
03493 smlTrace(TRACE_EXIT, "%s", __func__);
03494 return devinf;
03495
03496 error:
03497 if (parser && parser->reader) {
03498 xmlFreeTextReader(parser->reader);
03499 parser->reader = NULL;
03500 }
03501 if (parser)
03502 smlSafeFree((gpointer *)&parser);
03503 if (devinf)
03504 smlDevInfUnref(devinf);
03505 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
03506 return NULL;
03507 }
03508