ua_xml.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. #include "ua_types_generated.h"
  2. #include "ua_types_encoding_xml.h"
  3. #include "ua_xml.h"
  4. #include "ua_namespace_xml.h"
  5. #include <fcntl.h> // open, O_RDONLY
  6. UA_Int32 UA_TypedArray_init(UA_TypedArray *p) {
  7. p->size = -1;
  8. p->vt = &UA_.types[UA_INVALIDTYPE];
  9. p->elements = UA_NULL;
  10. return UA_SUCCESS;
  11. }
  12. UA_Int32 UA_TypedArray_new(UA_TypedArray **p) {
  13. UA_alloc((void ** )p, sizeof(UA_TypedArray));
  14. UA_TypedArray_init(*p);
  15. return UA_SUCCESS;
  16. }
  17. UA_Int32 UA_TypedArray_setType(UA_TypedArray *p, UA_Int32 type) {
  18. UA_Int32 retval = UA_ERR_INVALID_VALUE;
  19. if(type >= UA_BOOLEAN && type <= UA_INVALIDTYPE) {
  20. p->vt = &UA_.types[type];
  21. retval = UA_SUCCESS;
  22. }
  23. return retval;
  24. }
  25. // FIXME: We might want to have these classes and their methods
  26. // defined in opcua.h via generate_builtin and the plugin-concept
  27. // or in ua_basictypes.c
  28. UA_Int32 UA_NodeSetAlias_init(UA_NodeSetAlias *p) {
  29. UA_String_init(&(p->alias));
  30. UA_String_init(&(p->value));
  31. return UA_SUCCESS;
  32. }
  33. UA_Int32 UA_NodeSetAlias_new(UA_NodeSetAlias **p) {
  34. UA_alloc((void ** )p, sizeof(UA_NodeSetAlias));
  35. UA_NodeSetAlias_init(*p);
  36. return UA_SUCCESS;
  37. }
  38. UA_Int32 UA_NodeSetAliases_init(UA_NodeSetAliases *p) {
  39. p->size = -1;
  40. p->aliases = UA_NULL;
  41. return UA_SUCCESS;
  42. }
  43. UA_Int32 UA_NodeSetAliases_new(UA_NodeSetAliases **p) {
  44. UA_alloc((void ** )p, sizeof(UA_NodeSetAliases));
  45. UA_NodeSetAliases_init(*p);
  46. return UA_SUCCESS;
  47. }
  48. UA_Int32 UA_NodeSetAliases_println(cstring label, UA_NodeSetAliases *p) {
  49. UA_Int32 i;
  50. for(i = 0;i < p->size;i++) {
  51. UA_NodeSetAlias *a = p->aliases[i];
  52. printf("%s{addr=%p", label, (void *)a);
  53. if(a)
  54. printf(",alias='%.*s', value='%.*s'", a->alias.length, a->alias.data, a->value.length, a->value.data);
  55. printf("}\n");
  56. }
  57. return UA_SUCCESS;
  58. }
  59. UA_Int32 UA_NodeSet_init(UA_NodeSet *p, UA_UInt32 nsid) {
  60. Namespace_new(&(p->ns), 100, nsid);
  61. p->aliases.size = -1;
  62. p->aliases.aliases = UA_NULL;
  63. return UA_SUCCESS;
  64. }
  65. UA_Int32 UA_NodeSet_new(UA_NodeSet **p, UA_UInt32 nsid) {
  66. UA_alloc((void ** )p, sizeof(UA_NodeSet));
  67. UA_NodeSet_init(*p, nsid);
  68. return UA_SUCCESS;
  69. }
  70. UA_Int32 _UA_NodeId_copycstring(cstring src, UA_NodeId* dst, UA_NodeSetAliases* aliases) {
  71. UA_Int32 retval = UA_SUCCESS;
  72. if (src != UA_NULL && dst != UA_NULL ) {
  73. if (src[0] == 'i' && src[1] == '=') { // namespace zero numeric identifier
  74. dst->identifier.numeric = atoi(&src[2]);
  75. } else if (src[0] == 'n' && src[1] == 's' && src[2] == '=') { // namespace
  76. dst->namespace = atoi(&src[3]);
  77. src = strchr(&src[3],';');
  78. if (src != UA_NULL)
  79. retval = _UA_NodeId_copycstring(src+1,dst,aliases); // +1 to start beyond ;
  80. else
  81. retval = UA_ERR_INVALID_VALUE;
  82. } else if (aliases != UA_NULL ) { // try for aliases
  83. UA_Int32 i;
  84. for (i = 0; i < aliases->size && dst->identifier.numeric == 0; ++i) {
  85. if (0 == strncmp((char const*) src, (char const*) aliases->aliases[i]->alias.data,
  86. aliases->aliases[i]->alias.length)) {
  87. _UA_NodeId_copycstring((cstring)aliases->aliases[i]->alias.data,dst,UA_NULL); // substitute text of alias
  88. }
  89. }
  90. } else {
  91. retval = UA_ERR_NOT_IMPLEMENTED;
  92. }
  93. } else {
  94. retval = UA_ERR_INVALID_VALUE;
  95. }
  96. DBG_VERBOSE(printf("UA_NodeId_copycstring src=%s,id=%d\n", src, dst->identifier.numeric));
  97. return retval;
  98. }
  99. UA_Int32 UA_NodeId_copycstring(cstring src, UA_NodeId* dst, UA_NodeSetAliases* aliases) {
  100. dst->encodingByte = UA_NODEIDTYPE_FOURBYTE;
  101. dst->namespace = 0;
  102. dst->identifier.numeric = 0;
  103. return _UA_NodeId_copycstring(src,dst,aliases);
  104. }
  105. UA_Int32 UA_ReferenceNode_println(cstring label, UA_ReferenceNode *a) {
  106. printf("%s{referenceType=%d, target=%d, isInverse=%d}\n",
  107. label,
  108. a->referenceTypeId.identifier.numeric,
  109. a->targetId.nodeId.identifier.numeric,
  110. a->isInverse);
  111. return UA_SUCCESS;
  112. }
  113. UA_Int32 UA_ExpandedNodeId_copycstring(cstring src, UA_ExpandedNodeId *dst, UA_NodeSetAliases *aliases) {
  114. dst->nodeId.encodingByte = UA_NODEIDTYPE_FOURBYTE;
  115. dst->nodeId.namespace = 0;
  116. dst->nodeId.identifier.numeric = 0;
  117. UA_NodeId_copycstring(src, &(dst->nodeId), aliases);
  118. DBG_VERBOSE(printf("UA_ExpandedNodeId_copycstring src=%s,id=%d\n", src, dst->nodeId.identifier.numeric));
  119. return UA_SUCCESS;
  120. }
  121. void XML_Stack_init(XML_Stack* p, UA_UInt32 nsid, cstring name) {
  122. unsigned int i, j;
  123. p->depth = 0;
  124. for(i = 0;i < XML_STACK_MAX_DEPTH;i++) {
  125. p->parent[i].name = UA_NULL;
  126. p->parent[i].len = 0;
  127. p->parent[i].activeChild = -1;
  128. p->parent[i].textAttrib = UA_NULL;
  129. p->parent[i].textAttribIdx = -1;
  130. /* p->parent[i].totalGatherLength = -1; */
  131. /* UA_list_init(&(p->parent[i].textGatherList)); */
  132. for (j = 0; j < XML_STACK_MAX_CHILDREN; j++) {
  133. p->parent[i].children[j].name = UA_NULL;
  134. p->parent[i].children[j].length = -1;
  135. p->parent[i].children[j].elementHandler = UA_NULL;
  136. p->parent[i].children[j].type = UA_INVALIDTYPE;
  137. p->parent[i].children[j].obj = UA_NULL;
  138. }
  139. }
  140. /* p->nsid = nsid; */
  141. p->parent[0].name = name;
  142. }
  143. char path_buffer[1024];
  144. char *XML_Stack_path(XML_Stack *s) {
  145. UA_Int32 i;
  146. char *p = &path_buffer[0];
  147. for(i = 0;i <= s->depth;i++) {
  148. strcpy(p, s->parent[i].name);
  149. p += strlen(s->parent[i].name);
  150. *p = '/';
  151. p++;
  152. }
  153. *p = 0;
  154. return &path_buffer[0];
  155. }
  156. void XML_Stack_print(XML_Stack *s) {
  157. printf("%s", XML_Stack_path(s));
  158. }
  159. // FIXME: we might want to calculate textAttribIdx from a string and the information given on the stack
  160. void XML_Stack_handleTextAsElementOf(XML_Stack *p, cstring textAttrib, unsigned int textAttribIdx) {
  161. p->parent[p->depth].textAttrib = textAttrib;
  162. p->parent[p->depth].textAttribIdx = textAttribIdx;
  163. }
  164. void XML_Stack_addChildHandler(XML_Stack *p, cstring name, UA_Int32 length, XML_decoder handler, UA_Int32 type,
  165. void *dst) {
  166. unsigned int len = p->parent[p->depth].len;
  167. p->parent[p->depth].children[len].name = name;
  168. p->parent[p->depth].children[len].length = length;
  169. p->parent[p->depth].children[len].elementHandler = handler;
  170. p->parent[p->depth].children[len].type = type;
  171. p->parent[p->depth].children[len].obj = dst;
  172. p->parent[p->depth].len++;
  173. }
  174. UA_Int32 UA_Text_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_Byte **dst, _Bool isStart) {
  175. DBG_VERBOSE(printf("UA_String entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
  176. UA_UInt32 i;
  177. if(isStart) {
  178. if(dst == UA_NULL) {
  179. UA_alloc((void **)&dst, sizeof(void *));
  180. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
  181. }
  182. // set attributes
  183. for(i = 0;attr[i];i += 2) {
  184. if(0 == strncmp("Data", attr[i], strlen("Data"))) {
  185. char *tmp;
  186. UA_alloc((void **)&tmp, strlen(attr[i+1])+1);
  187. strncpy(tmp, attr[i+1], strlen(attr[i+1]));
  188. tmp[strlen(attr[i+1])] = 0;
  189. *dst = (UA_Byte *)tmp;
  190. } else
  191. printf("UA_Text_decodeXml - Unknown attribute - name=%s, value=%s\n", attr[i], attr[i+1]);
  192. }
  193. }
  194. return UA_SUCCESS;
  195. }
  196. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  197. /* UA_Int32 UA_ReferenceNode_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_ReferenceNode* dst, _Bool isStart) { */
  198. /* DBG_VERBOSE(printf("UA_ReferenceNode_decodeXML entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  199. /* if (isStart) { */
  200. /* // create if necessary */
  201. /* if (dst == UA_NULL) { */
  202. /* UA_ReferenceNode_new(&dst); */
  203. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  204. /* } */
  205. /* // set handlers */
  206. /* s->parent[s->depth].len = 0; */
  207. /* XML_Stack_addChildHandler(s, "ReferenceType", strlen("ReferenceType"),(XML_decoder) UA_NodeId_decodeXmlFromStack, UA_NODEID, &(dst->referenceTypeId)); */
  208. /* XML_Stack_addChildHandler(s, "IsForward", strlen("IsForward"), (XML_decoder) UA_Boolean_decodeXmlFromStack, UA_BOOLEAN, &(dst->isInverse)); */
  209. /* XML_Stack_addChildHandler(s, "Target", strlen("Target"), (XML_decoder) UA_ExpandedNodeId_decodeXmlFromStack, UA_EXPANDEDNODEID, &(dst->targetId)); */
  210. /* XML_Stack_handleTextAsElementOf(s, "NodeId", 2); */
  211. /* // set attributes */
  212. /* UA_Int32 i; */
  213. /* for (i = 0; attr[i]; i += 2) { */
  214. /* if (0 == strncmp("ReferenceType", attr[i], strlen("ReferenceType"))) { */
  215. /* UA_NodeId_copycstring(attr[i + 1], &(dst->referenceTypeId), s->aliases); */
  216. /* } else if (0 == strncmp("IsForward", attr[i], strlen("IsForward"))) { */
  217. /* UA_Boolean_copycstring(attr[i + 1], &(dst->isInverse)); */
  218. /* dst->isInverse = !dst->isInverse; */
  219. /* } else if (0 == strncmp("Target", attr[i], strlen("Target"))) { */
  220. /* UA_ExpandedNodeId_copycstring(attr[i + 1], &(dst->targetId), s->aliases); */
  221. /* } else { */
  222. /* DBG_ERR(XML_Stack_print(s));DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  223. /* } */
  224. /* } */
  225. /* } */
  226. /* return UA_SUCCESS; */
  227. /* } */
  228. UA_Int32 UA_TypedArray_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_TypedArray* dst, _Bool isStart) {
  229. UA_Int32 type = s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].type;
  230. /* DBG_VERBOSE(printf("UA_TypedArray_decodeXML - entered with dst=%p,isStart=%d,type={%d,%s},name=%s\n", (void* ) dst, isStart,type,UA_[type].name, names)); */
  231. if (isStart) {
  232. if (dst == UA_NULL) {
  233. UA_TypedArray_new(&dst);
  234. UA_TypedArray_setType(dst, type);
  235. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = dst;
  236. }
  237. // need to map from ArrayName to member name
  238. // References - Reference
  239. // Aliases - Alias
  240. // ListOfXX - XX
  241. DBG(UA_Int32 length = 0;
  242. cstring names = s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].name;
  243. if (0 == strncmp("ListOf",names,strlen("ListOf"))) {
  244. names = &names[strlen("ListOf")];
  245. length = strlen(names);
  246. } else if ( 0 == strncmp("References",names,strlen("References"))){
  247. length = strlen(names) - 1;
  248. } else if ( 0 == strncmp("Aliases",names,strlen("Aliases"))){
  249. length = strlen(names) - 2;
  250. }
  251. printf("UA_TypedArray_decodeXML - add handler for {%.*s}\n", length, names));
  252. // this is problematic as the standard encoding functions in the vtable take a bytestring as the input
  253. /* XML_Stack_addChildHandler(s, names, length, (XML_decoder) UA_.types[type].encodings[1].decode, type, UA_NULL); */
  254. } else {
  255. // sub element is ready, add to array
  256. if (dst->size < 0 || dst->size == 0) {
  257. dst->size = 1;
  258. UA_alloc((void** )&(dst->elements), dst->size * sizeof(void*));
  259. DBG(printf("UA_TypedArray_decodeXML - allocate elements:dst=%p, aliases=%p, size=%d\n", (void* )dst, (void* )(dst->elements),dst->size));
  260. } else {
  261. dst->size++;
  262. dst->elements = realloc(dst->elements, dst->size * sizeof(void*));
  263. DBG(printf("UA_TypedArray_decodeXML - reallocate elements:dst=%p, aliases=%p, size=%d\n", (void* )dst,(void* )(dst->elements), dst->size));
  264. }
  265. // index starts with 0, therefore size-1
  266. DBG_VERBOSE(printf("UA_TypedArray_decodeXML - assign element[%d], src=%p\n", dst->size - 1, (void* )attr));
  267. /* dst->elements[dst->size - 1] = (void*) attr; */
  268. DBG_VERBOSE(printf("UA_TypedArray_decodeXML - clear %p\n",(void* ) (s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj)));
  269. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL;
  270. }
  271. return UA_SUCCESS;
  272. }
  273. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  274. /* UA_Int32 UA_DataTypeNode_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_DataTypeNode* dst, _Bool isStart) { */
  275. /* DBG_VERBOSE(printf("UA_DataTypeNode entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  276. /* UA_UInt32 i; */
  277. /* if (isStart) { */
  278. /* // create a new object if called with UA_NULL */
  279. /* if (dst == UA_NULL) { */
  280. /* UA_DataTypeNode_new(&dst); */
  281. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  282. /* } */
  283. /* s->parent[s->depth].len = 0; */
  284. /* XML_Stack_addChildHandler(s, "DisplayName", strlen("DisplayName"), (XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->displayName)); */
  285. /* XML_Stack_addChildHandler(s, "Description", strlen("Description"),(XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->description)); */
  286. /* XML_Stack_addChildHandler(s, "BrowseName", strlen("BrowseName"),(XML_decoder) UA_QualifiedName_decodeXmlFromStack, UA_QUALIFIEDNAME, &(dst->description)); */
  287. /* XML_Stack_addChildHandler(s, "IsAbstract", strlen("IsAbstract"),(XML_decoder) UA_Boolean_decodeXmlFromStack, UA_BOOLEAN, &(dst->description)); */
  288. /* XML_Stack_addChildHandler(s, "References", strlen("References"),(XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_REFERENCENODE, UA_NULL); */
  289. /* // set missing default attributes */
  290. /* dst->nodeClass = UA_NODECLASS_DATATYPE; */
  291. /* // set attributes */
  292. /* for (i = 0; attr[i]; i += 2) { */
  293. /* if (0 == strncmp("NodeId", attr[i], strlen("NodeId"))) { */
  294. /* UA_NodeId_copycstring(attr[i + 1], &(dst->nodeId), s->aliases); */
  295. /* } else if (0 == strncmp("BrowseName", attr[i], strlen("BrowseName"))) { */
  296. /* UA_String_copycstring(attr[i + 1], &(dst->browseName.name)); */
  297. /* dst->browseName.namespaceIndex = 0; */
  298. /* } else if (0 == strncmp("DisplayName", attr[i], strlen("DisplayName"))) { */
  299. /* UA_String_copycstring(attr[i + 1], &(dst->displayName.text)); */
  300. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  301. /* } else if (0 == strncmp("IsAbstract", attr[i], strlen("IsAbstract"))) { */
  302. /* UA_Boolean_copycstring(attr[i + 1], &(dst->isAbstract)); */
  303. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  304. /* } else if (0 == strncmp("Description", attr[i], strlen("Description"))) { */
  305. /* UA_String_copycstring(attr[i + 1], &(dst->description.text)); */
  306. /* dst->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  307. /* } else { */
  308. /* DBG_ERR(XML_Stack_print(s));DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  309. /* } */
  310. /* } */
  311. /* } else { */
  312. /* switch (s->parent[s->depth - 1].activeChild) { */
  313. /* case 4: // References */
  314. /* if (attr != UA_NULL) { */
  315. /* UA_TypedArray* array = (UA_TypedArray *) attr; */
  316. /* DBG_VERBOSE(printf("finished aliases: references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  317. /* dst->referencesSize = array->size; */
  318. /* /\* dst->references = (UA_ReferenceNode**) array->elements; *\/ */
  319. /* } */
  320. /* break; */
  321. /* } */
  322. /* } */
  323. /* return UA_SUCCESS; */
  324. /* } */
  325. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  326. /* UA_Int32 UA_ObjectTypeNode_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_ObjectTypeNode* dst, _Bool isStart) { */
  327. /* DBG_VERBOSE(printf("UA_DataTypeNode entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  328. /* UA_UInt32 i; */
  329. /* if (isStart) { */
  330. /* // create a new object if called with UA_NULL */
  331. /* if (dst == UA_NULL) { */
  332. /* UA_ObjectTypeNode_new(&dst); */
  333. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  334. /* } */
  335. /* s->parent[s->depth].len = 0; */
  336. /* XML_Stack_addChildHandler(s, "DisplayName", strlen("DisplayName"), (XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->displayName)); */
  337. /* XML_Stack_addChildHandler(s, "Description", strlen("Description"),(XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->description)); */
  338. /* XML_Stack_addChildHandler(s, "BrowseName", strlen("BrowseName"),(XML_decoder) UA_QualifiedName_decodeXmlFromStack, UA_QUALIFIEDNAME, &(dst->description)); */
  339. /* XML_Stack_addChildHandler(s, "IsAbstract", strlen("IsAbstract"),(XML_decoder) UA_Boolean_decodeXmlFromStack, UA_BOOLEAN, &(dst->description)); */
  340. /* XML_Stack_addChildHandler(s, "References", strlen("References"),(XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_REFERENCENODE, UA_NULL); */
  341. /* // set missing default attributes */
  342. /* dst->nodeClass = UA_NODECLASS_OBJECTTYPE; */
  343. /* // set attributes */
  344. /* for (i = 0; attr[i]; i += 2) { */
  345. /* if (0 == strncmp("NodeId", attr[i], strlen("NodeId"))) { */
  346. /* UA_NodeId_copycstring(attr[i + 1], &(dst->nodeId), s->aliases); */
  347. /* } else if (0 == strncmp("BrowseName", attr[i], strlen("BrowseName"))) { */
  348. /* UA_String_copycstring(attr[i + 1], &(dst->browseName.name)); */
  349. /* dst->browseName.namespaceIndex = 0; */
  350. /* } else if (0 == strncmp("DisplayName", attr[i], strlen("DisplayName"))) { */
  351. /* UA_String_copycstring(attr[i + 1], &(dst->displayName.text)); */
  352. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  353. /* } else if (0 == strncmp("IsAbstract", attr[i], strlen("IsAbstract"))) { */
  354. /* UA_Boolean_copycstring(attr[i + 1], &(dst->isAbstract)); */
  355. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  356. /* } else if (0 == strncmp("Description", attr[i], strlen("Description"))) { */
  357. /* UA_String_copycstring(attr[i + 1], &(dst->description.text)); */
  358. /* dst->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  359. /* } else { */
  360. /* DBG_ERR(XML_Stack_print(s));DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  361. /* } */
  362. /* } */
  363. /* } else { */
  364. /* switch (s->parent[s->depth - 1].activeChild) { */
  365. /* case 4: // References */
  366. /* if (attr != UA_NULL) { */
  367. /* UA_TypedArray* array = (UA_TypedArray *) attr; */
  368. /* DBG_VERBOSE(printf("finished aliases: references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  369. /* dst->referencesSize = array->size; */
  370. /* /\* dst->references = (UA_ReferenceNode**) array->elements; *\/ */
  371. /* } */
  372. /* break; */
  373. /* } */
  374. /* } */
  375. /* return UA_SUCCESS; */
  376. /* } */
  377. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  378. /* UA_Int32 UA_VariableTypeNode_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_VariableTypeNode* dst, _Bool isStart) { */
  379. /* DBG_VERBOSE(printf("UA_DataTypeNode entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  380. /* UA_UInt32 i; */
  381. /* if (isStart) { */
  382. /* // create a new object if called with UA_NULL */
  383. /* if (dst == UA_NULL) { */
  384. /* UA_VariableTypeNode_new(&dst); */
  385. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  386. /* } */
  387. /* s->parent[s->depth].len = 0; */
  388. /* XML_Stack_addChildHandler(s, "DisplayName", strlen("DisplayName"), (XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->displayName)); */
  389. /* XML_Stack_addChildHandler(s, "Description", strlen("Description"),(XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->description)); */
  390. /* XML_Stack_addChildHandler(s, "BrowseName", strlen("BrowseName"),(XML_decoder) UA_QualifiedName_decodeXmlFromStack, UA_QUALIFIEDNAME, &(dst->description)); */
  391. /* XML_Stack_addChildHandler(s, "IsAbstract", strlen("IsAbstract"),(XML_decoder) UA_Boolean_decodeXmlFromStack, UA_BOOLEAN, &(dst->description)); */
  392. /* XML_Stack_addChildHandler(s, "References", strlen("References"),(XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_REFERENCENODE, UA_NULL); */
  393. /* // set missing default attributes */
  394. /* dst->nodeClass = UA_NODECLASS_VARIABLETYPE; */
  395. /* // set attributes */
  396. /* for (i = 0; attr[i]; i += 2) { */
  397. /* if (0 == strncmp("NodeId", attr[i], strlen("NodeId"))) { */
  398. /* UA_NodeId_copycstring(attr[i + 1], &(dst->nodeId), s->aliases); */
  399. /* } else if (0 == strncmp("BrowseName", attr[i], strlen("BrowseName"))) { */
  400. /* UA_String_copycstring(attr[i + 1], &(dst->browseName.name)); */
  401. /* dst->browseName.namespaceIndex = 0; */
  402. /* } else if (0 == strncmp("DisplayName", attr[i], strlen("DisplayName"))) { */
  403. /* UA_String_copycstring(attr[i + 1], &(dst->displayName.text)); */
  404. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  405. /* } else if (0 == strncmp("IsAbstract", attr[i], strlen("IsAbstract"))) { */
  406. /* UA_Boolean_copycstring(attr[i + 1], &(dst->isAbstract)); */
  407. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  408. /* } else if (0 == strncmp("Description", attr[i], strlen("Description"))) { */
  409. /* UA_String_copycstring(attr[i + 1], &(dst->description.text)); */
  410. /* dst->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  411. /* } else { */
  412. /* DBG_ERR(XML_Stack_print(s));DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  413. /* } */
  414. /* } */
  415. /* } else { */
  416. /* switch (s->parent[s->depth - 1].activeChild) { */
  417. /* case 4: // References */
  418. /* if (attr != UA_NULL) { */
  419. /* UA_TypedArray* array = (UA_TypedArray *) attr; */
  420. /* DBG_VERBOSE(printf("finished aliases: references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  421. /* dst->referencesSize = array->size; */
  422. /* /\* dst->references = (UA_ReferenceNode**) array->elements; *\/ */
  423. /* } */
  424. /* break; */
  425. /* } */
  426. /* } */
  427. /* return UA_SUCCESS; */
  428. /* } */
  429. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  430. /* UA_Int32 UA_ObjectNode_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_ObjectNode* dst, _Bool isStart) { */
  431. /* DBG_VERBOSE(printf("UA_ObjectNode entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  432. /* UA_UInt32 i; */
  433. /* if (isStart) { */
  434. /* // create a new object if called with UA_NULL */
  435. /* if (dst == UA_NULL) { */
  436. /* UA_ObjectNode_new(&dst); */
  437. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  438. /* } */
  439. /* XML_Stack_addChildHandler(s, "DisplayName", strlen("DisplayName"), (XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->displayName)); */
  440. /* XML_Stack_addChildHandler(s, "Description", strlen("Description"), (XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, &(dst->description)); */
  441. /* XML_Stack_addChildHandler(s, "BrowseName", strlen("BrowseName"), (XML_decoder) UA_QualifiedName_decodeXmlFromStack, UA_QUALIFIEDNAME, &(dst->browseName)); */
  442. /* XML_Stack_addChildHandler(s, "SymbolicName", strlen("SymbolicName"), (XML_decoder) UA_QualifiedName_decodeXmlFromStack, UA_QUALIFIEDNAME,&(dst->browseName)); */
  443. /* XML_Stack_addChildHandler(s, "References", strlen("References"), (XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_REFERENCENODE, UA_NULL); */
  444. /* // set missing default attributes */
  445. /* dst->nodeClass = UA_NODECLASS_OBJECT; */
  446. /* // set attributes */
  447. /* for (i = 0; attr[i]; i += 2) { */
  448. /* if (0 == strncmp("NodeId", attr[i], strlen("NodeId"))) { */
  449. /* UA_NodeId_copycstring(attr[i + 1], &(dst->nodeId), s->aliases); */
  450. /* } else if (0 == strncmp("SymbolicName", attr[i], strlen("SymbolicName"))) { */
  451. /* UA_String_copycstring(attr[i + 1], &(dst->browseName.name)); */
  452. /* dst->browseName.namespaceIndex = 0; */
  453. /* } else if (0 == strncmp("BrowseName", attr[i], strlen("BrowseName"))) { */
  454. /* UA_String_copycstring(attr[i + 1], &(dst->browseName.name)); */
  455. /* dst->browseName.namespaceIndex = 0; */
  456. /* } else if (0 == strncmp("DisplayName", attr[i], strlen("DisplayName"))) { */
  457. /* UA_String_copycstring(attr[i + 1], &(dst->displayName.text)); */
  458. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  459. /* } else if (0 == strncmp("Description", attr[i], strlen("Description"))) { */
  460. /* UA_String_copycstring(attr[i + 1], &(dst->description.text)); */
  461. /* dst->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  462. /* } else { */
  463. /* DBG_ERR(XML_Stack_print(s));DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  464. /* } */
  465. /* } */
  466. /* } else { */
  467. /* if (s->parent[s->depth - 1].activeChild == 4 && attr != UA_NULL ) { // References Array */
  468. /* UA_TypedArray* array = (UA_TypedArray*) attr; */
  469. /* DBG(printf("UA_ObjectNode_decodeXML finished references: references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  470. /* dst->referencesSize = array->size; */
  471. /* /\* dst->references = (UA_ReferenceNode**) array->elements; *\/ */
  472. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL; */
  473. /* } */
  474. /* } */
  475. /* return UA_SUCCESS; */
  476. /* } */
  477. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  478. /* UA_Int32 UA_Variant_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_Variant* dst, _Bool isStart) { */
  479. /* DBG_VERBOSE(printf("UA_Variant entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  480. /* UA_UInt32 i; */
  481. /* if (isStart) { */
  482. /* // create a new object if called with UA_NULL */
  483. /* if (dst == UA_NULL) { */
  484. /* UA_Variant_new(&dst); */
  485. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  486. /* } */
  487. /* s->parent[s->depth].len = 0; */
  488. /* XML_Stack_addChildHandler(s, "ListOfExtensionObject", strlen("ListOfExtensionObject"), (XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_EXTENSIONOBJECT, UA_NULL); */
  489. /* XML_Stack_addChildHandler(s, "ListOfLocalizedText", strlen("ListOfLocalizedText"), (XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_LOCALIZEDTEXT, UA_NULL); */
  490. /* // set attributes */
  491. /* for (i = 0; attr[i]; i += 2) { */
  492. /* { */
  493. /* DBG_ERR(XML_Stack_print(s)); */
  494. /* DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  495. /* } */
  496. /* } */
  497. /* } else { */
  498. /* if (s->parent[s->depth - 1].activeChild == 0 && attr != UA_NULL ) { // ExtensionObject */
  499. /* UA_TypedArray* array = (UA_TypedArray*) attr; */
  500. /* DBG_VERBOSE(printf("UA_Variant_decodeXML - finished array: references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  501. /* dst->arrayLength = array->size; */
  502. /* dst->data = array->elements; */
  503. /* dst->vt = &UA_.types[UA_EXTENSIONOBJECT]; */
  504. /* dst->encodingMask = UA_EXTENSIONOBJECT_NS0 & UA_VARIANT_ENCODINGMASKTYPE_ARRAY; */
  505. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL; */
  506. /* } else if (s->parent[s->depth - 1].activeChild == 1 && attr != UA_NULL ) { // LocalizedText */
  507. /* UA_TypedArray* array = (UA_TypedArray*) attr; */
  508. /* DBG_VERBOSE(printf("UA_Variant_decodeXML - finished array: references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  509. /* dst->arrayLength = array->size; */
  510. /* dst->data = array->elements; */
  511. /* dst->vt = &UA_.types[UA_LOCALIZEDTEXT]; */
  512. /* dst->encodingMask = UA_LOCALIZEDTEXT_NS0 & UA_VARIANT_ENCODINGMASKTYPE_ARRAY; */
  513. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL; */
  514. /* } */
  515. /* } */
  516. /* return UA_SUCCESS; */
  517. /* } */
  518. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  519. /* UA_Int32 UA_ExtensionObject_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_ExtensionObject* dst, _Bool isStart) { */
  520. /* DBG_VERBOSE(printf("UA_ExtensionObject entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  521. /* UA_UInt32 i; */
  522. /* if (isStart) { */
  523. /* // create a new object if called with UA_NULL */
  524. /* if (dst == UA_NULL) { */
  525. /* UA_ExtensionObject_new(&dst); */
  526. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  527. /* } */
  528. /* s->parent[s->depth].len = 0; */
  529. /* XML_Stack_addChildHandler(s, "TypeId", strlen("TypeId"), (XML_decoder) UA_NodeId_decodeXmlFromStack, UA_NODEID, &(dst->typeId)); */
  530. /* // XML_Stack_addChildHandler(s, "Body", strlen("Body"), (XML_decoder) UA_Body_decodeXML, UA_LOCALIZEDTEXT, UA_NULL); */
  531. /* // set attributes */
  532. /* for (i = 0; attr[i]; i += 2) { */
  533. /* { */
  534. /* DBG_ERR(XML_Stack_print(s)); */
  535. /* DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  536. /* } */
  537. /* } */
  538. /* } */
  539. /* return UA_SUCCESS; */
  540. /* } */
  541. _Bool UA_NodeId_isBuiltinType(UA_NodeId* nodeid) {
  542. return (nodeid->namespace == 0 &&
  543. nodeid->identifier.numeric >= UA_BOOLEAN_NS0 &&
  544. nodeid->identifier.numeric <= UA_DIAGNOSTICINFO_NS0
  545. );
  546. }
  547. // Gets generated in ua_types_generated.h and .c. But currently only as stubs
  548. /* UA_Int32 UA_VariableNode_decodeXmlFromStack(XML_Stack* s, XML_Attr* attr, UA_VariableNode* dst, _Bool isStart) { */
  549. /* DBG_VERBOSE(printf("UA_VariableNode entered with dst=%p,isStart=%d\n", (void* ) dst, isStart)); */
  550. /* UA_UInt32 i; */
  551. /* if (isStart) { */
  552. /* // create a new object if called with UA_NULL */
  553. /* if (dst == UA_NULL) { */
  554. /* UA_VariableNode_new(&dst); */
  555. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void*) dst; */
  556. /* } */
  557. /* s->parent[s->depth].len = 0; */
  558. /* XML_Stack_addChildHandler(s, "DisplayName", strlen("DisplayName"), (XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, */
  559. /* &(dst->displayName)); */
  560. /* XML_Stack_addChildHandler(s, "Description", strlen("Description"),(XML_decoder) UA_LocalizedText_decodeXmlFromStack, UA_LOCALIZEDTEXT, */
  561. /* &(dst->description)); */
  562. /* XML_Stack_addChildHandler(s, "DataType", strlen("DataType"),(XML_decoder) UA_NodeId_decodeXmlFromStack, UA_NODEID, &(dst->dataType)); */
  563. /* XML_Stack_addChildHandler(s, "ValueRank", strlen("ValueRank"),(XML_decoder) UA_Int32_decodeXmlFromStack, UA_INT32, &(dst->valueRank)); */
  564. /* XML_Stack_addChildHandler(s, "Value", strlen("Value"),(XML_decoder) UA_Variant_decodeXmlFromStack, UA_VARIANT, &(dst->value)); */
  565. /* XML_Stack_addChildHandler(s, "References", strlen("References"), (XML_decoder) UA_TypedArray_decodeXmlFromStack, UA_REFERENCENODE, */
  566. /* UA_NULL); */
  567. /* // set missing default attributes */
  568. /* dst->nodeClass = UA_NODECLASS_VARIABLE; */
  569. /* // set attributes */
  570. /* for (i = 0; attr[i]; i += 2) { */
  571. /* if (0 == strncmp("NodeId", attr[i], strlen("NodeId"))) { */
  572. /* UA_NodeId_copycstring(attr[i + 1], &(dst->nodeId), s->aliases); */
  573. /* } else if (0 == strncmp("DataType", attr[i], strlen("DataType"))) { */
  574. /* UA_NodeId_copycstring(attr[i + 1], &(dst->dataType), s->aliases); */
  575. /* if (UA_NodeId_isBuiltinType(&(dst->dataType))) { */
  576. /* dst->value.encodingMask = dst->dataType.identifier.numeric; */
  577. /* dst->value.vt = &UA_.types[UA_ns0ToVTableIndex(&dst->dataType)]; */
  578. /* } else { */
  579. /* dst->value.encodingMask = UA_EXTENSIONOBJECT_NS0; */
  580. /* dst->value.vt = &UA_.types[UA_EXTENSIONOBJECT]; */
  581. /* } */
  582. /* } else if (0 == strncmp("ValueRank", attr[i], strlen("ValueRank"))) { */
  583. /* dst->valueRank = atoi(attr[i + 1]); */
  584. /* } else if (0 == strncmp("ParentNodeId", attr[i], strlen("ParentNodeId"))) { */
  585. /* // FIXME: this seems to be redundant to the hasProperty-reference */
  586. /* } else if (0 == strncmp("BrowseName", attr[i], strlen("BrowseName"))) { */
  587. /* UA_String_copycstring(attr[i + 1], &(dst->browseName.name)); */
  588. /* dst->browseName.namespaceIndex = 0; */
  589. /* } else if (0 == strncmp("DisplayName", attr[i], strlen("DisplayName"))) { */
  590. /* UA_String_copycstring(attr[i + 1], &(dst->displayName.text)); */
  591. /* dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  592. /* } else if (0 == strncmp("Description", attr[i], strlen("Description"))) { */
  593. /* UA_String_copycstring(attr[i + 1], &(dst->description.text)); */
  594. /* dst->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT; */
  595. /* } else { */
  596. /* DBG_ERR(XML_Stack_print(s)); */
  597. /* DBG_ERR(printf("%s - unknown attribute\n", attr[i])); */
  598. /* } */
  599. /* } */
  600. /* } else { */
  601. /* if (s->parent[s->depth - 1].activeChild == 5 && attr != UA_NULL) { // References */
  602. /* UA_TypedArray* array = (UA_TypedArray*) attr; */
  603. /* DBG(printf("UA_VariableNode_decodeXML - finished references=%p, size=%d\n",(void*)array,(array==UA_NULL)?-1:array->size)); */
  604. /* dst->referencesSize = array->size; */
  605. /* /\* dst->references = (UA_ReferenceNode**) array->elements; *\/ */
  606. /* s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL; */
  607. /* } */
  608. /* } */
  609. /* return UA_SUCCESS; */
  610. /* } */
  611. #ifdef DEBUG
  612. void print_node(UA_Node const * node) {
  613. if (node != UA_NULL) {
  614. UA_NodeId_printf("node.nodeId=", &(node->nodeId));
  615. printf("\t.browseName='%.*s'\n", node->browseName.name.length, node->browseName.name.data);
  616. printf("\t.displayName='%.*s'\n", node->displayName.text.length, node->displayName.text.data);
  617. printf("\t.description='%.*s%s'\n", node->description.text.length > 40 ? 40 : node->description.text.length,
  618. node->description.text.data, node->description.text.length > 40 ? "..." : "");
  619. printf("\t.nodeClass=%d\n", node->nodeClass);
  620. printf("\t.writeMask=%d\n", node->writeMask);
  621. printf("\t.userWriteMask=%d\n", node->userWriteMask);
  622. printf("\t.references.size=%d\n", node->referencesSize);
  623. UA_Int32 i;
  624. for(i = 0;i < node->referencesSize;i++) {
  625. printf("\t\t.element[%d]", i);
  626. UA_ReferenceNode_println("=", &node->references[i]);
  627. }
  628. switch(node->nodeClass) {
  629. case UA_NODECLASS_VARIABLE:
  630. {
  631. UA_VariableNode const *p = (UA_VariableNode const *)node;
  632. printf("\t----- UA_VariableNode ----- \n");
  633. UA_NodeId_printf("\t.dataType=", &(p->dataType));
  634. printf("\t.valueRank=%d\n", p->valueRank);
  635. printf("\t.accessLevel=%d\n", p->accessLevel);
  636. printf("\t.userAccessLevel=%d\n", p->userAccessLevel);
  637. printf("\t.arrayDimensionsSize=%d\n", p->arrayDimensionsSize);
  638. printf("\t.minimumSamplingInterval=%f\n", p->minimumSamplingInterval);
  639. printf("\t.historizing=%d\n", p->historizing);
  640. printf("\t----- UA_Variant ----- \n");
  641. printf("\t.value.type.name=%s\n", p->value.vt->name);
  642. printf("\t.value.array.length=%d\n", p->value.arrayLength);
  643. UA_Int32 i;
  644. UA_Byte *data = (UA_Byte *)p->value.data;
  645. for(i = 0;i < p->value.arrayLength || (p->value.arrayLength == -1 && i == 0);++i) {
  646. UA_Byte *currentData = data + (i*p->value.vt->memSize);
  647. printf("\t.value.array.element[%d]=%p", i, currentData);
  648. switch(p->value.vt->typeId.identifier.numeric) {
  649. case UA_LOCALIZEDTEXT_NS0:
  650. {
  651. if(p->value.data != UA_NULL) {
  652. UA_LocalizedText *ltp = (UA_LocalizedText *)currentData;
  653. printf(",locale={%d,{%.*s}},text={%d,{%.*s}}", ltp->locale.length,
  654. ltp->locale.length, ltp->locale.data, ltp->text.length,
  655. ltp->text.length, ltp->text.data);
  656. }
  657. }
  658. break;
  659. case UA_EXTENSIONOBJECT_NS0:
  660. {
  661. if(p->value.data != UA_NULL) {
  662. UA_ExtensionObject *eo = (UA_ExtensionObject *)currentData;
  663. if(eo == UA_NULL)
  664. printf(",(null)");
  665. else
  666. printf(",enc=%d,typeId={i=%d}", eo->encoding, eo->typeId.identifier.numeric);
  667. }
  668. }
  669. break;
  670. default:
  671. break;
  672. }
  673. printf("\n");
  674. }
  675. }
  676. break;
  677. // case UA_NODECLASS_DATATYPE:
  678. default:
  679. break;
  680. }
  681. }
  682. }
  683. #endif
  684. UA_Int32 UA_NodeSetAlias_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_NodeSetAlias *dst, _Bool isStart) {
  685. DBG_VERBOSE(printf("UA_NodeSetAlias entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
  686. if(isStart) {
  687. // create if necessary
  688. if(dst == UA_NULL) {
  689. UA_NodeSetAlias_new(&dst);
  690. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
  691. }
  692. // set handlers
  693. s->parent[s->depth].len = 0;
  694. XML_Stack_addChildHandler(s, "Alias", strlen("Alias"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING,
  695. &(dst->alias));
  696. XML_Stack_addChildHandler(s, "Value", strlen("Value"), (XML_decoder)UA_String_decodeXmlFromStack, UA_STRING,
  697. &(dst->value));
  698. XML_Stack_handleTextAsElementOf(s, "Data", 1);
  699. // set attributes
  700. UA_Int32 i;
  701. for(i = 0;attr[i];i += 2) {
  702. if(0 == strncmp("Alias", attr[i], strlen("Alias")))
  703. UA_String_copycstring(attr[i + 1], &(dst->alias));
  704. else if(0 == strncmp("Value", attr[i], strlen("Value")))
  705. UA_String_copycstring(attr[i + 1], &(dst->value));
  706. else {
  707. DBG_ERR(XML_Stack_print(s)); DBG_ERR(printf("%s - unknown attribute\n", attr[i]));
  708. }
  709. }
  710. }
  711. return UA_SUCCESS;
  712. }
  713. UA_Int32 UA_NodeSetAliases_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_NodeSetAliases *dst, _Bool isStart) {
  714. DBG_VERBOSE(printf("UA_NodeSetALiases entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
  715. if(isStart) {
  716. if(dst == UA_NULL) {
  717. UA_NodeSetAliases_new(&dst);
  718. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
  719. }
  720. s->parent[s->depth].len = 0;
  721. XML_Stack_addChildHandler(s, "Alias", strlen(
  722. "Alias"), (XML_decoder)UA_NodeSetAlias_decodeXmlFromStack, UA_INVALIDTYPE,
  723. UA_NULL);
  724. } else {
  725. // sub element is ready, add to array
  726. if(dst->size < 0 || dst->size == 0) {
  727. dst->size = 1;
  728. UA_alloc((void ** )&(dst->aliases), dst->size * sizeof(UA_NodeSetAlias *));
  729. DBG_VERBOSE(
  730. printf("allocate aliases:dst=%p, aliases=%p, size=%d\n", (void * )dst, (void * )(dst->aliases),
  731. dst->size));
  732. } else {
  733. dst->size++;
  734. dst->aliases = realloc(dst->aliases, dst->size * sizeof(UA_NodeSetAlias *));
  735. DBG_VERBOSE(
  736. printf("reallocate aliases:dst=%p, aliases=%p, size=%d\n", (void * )dst, (void * )(dst->aliases),
  737. dst->size));
  738. }
  739. // index starts with 0, therefore size-1
  740. DBG_VERBOSE(printf("assign alias:dst=%p, src=%p\n", (void * )dst->aliases[dst->size - 1], (void * )attr));
  741. dst->aliases[dst->size - 1] = (UA_NodeSetAlias *)attr;
  742. DBG_VERBOSE(printf("UA_NodeSetAliases clears %p\n",
  743. (void * )(s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj)));
  744. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL;
  745. }
  746. return UA_SUCCESS;
  747. }
  748. UA_Int32 UA_NodeSet_decodeXmlFromStack(XML_Stack *s, XML_Attr *attr, UA_NodeSet *dst, _Bool isStart) {
  749. DBG_VERBOSE(printf("UA_NodeSet entered with dst=%p,isStart=%d\n", (void * )dst, isStart));
  750. if(isStart) {
  751. if(dst == UA_NULL) {
  752. UA_NodeSet_new(&dst, 99); // we don't really need the namespaceid for this..'
  753. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = (void *)dst;
  754. }
  755. s->parent[s->depth].len = 0;
  756. XML_Stack_addChildHandler(s, "Aliases", strlen(
  757. "Aliases"), (XML_decoder)UA_NodeSetAliases_decodeXmlFromStack, UA_INVALIDTYPE,
  758. &(dst->aliases));
  759. XML_Stack_addChildHandler(s, "UADataType", strlen(
  760. "UADataType"), (XML_decoder)UA_DataTypeNode_decodeXmlFromStack, UA_DATATYPENODE,
  761. UA_NULL);
  762. XML_Stack_addChildHandler(s, "UAVariableType", strlen(
  763. "UAVariableType"), (XML_decoder)UA_VariableTypeNode_decodeXmlFromStack,
  764. UA_VARIABLETYPENODE, UA_NULL);
  765. XML_Stack_addChildHandler(s, "UAVariable", strlen(
  766. "UAVariable"), (XML_decoder)UA_VariableNode_decodeXmlFromStack, UA_VARIABLENODE,
  767. UA_NULL);
  768. XML_Stack_addChildHandler(s, "UAObjectType", strlen(
  769. "UAObjectType"), (XML_decoder)UA_ObjectTypeNode_decodeXmlFromStack,
  770. UA_OBJECTTYPENODE, UA_NULL);
  771. XML_Stack_addChildHandler(s, "UAObject", strlen(
  772. "UAObject"), (XML_decoder)UA_ObjectNode_decodeXmlFromStack, UA_OBJECTNODE,
  773. UA_NULL);
  774. } else {
  775. if(s->parent[s->depth - 1].activeChild == 0 && attr != UA_NULL) {
  776. UA_NodeSetAliases *aliases = (UA_NodeSetAliases *)attr;
  777. DBG(printf("UA_NodeSet_decodeXml - finished aliases: aliases=%p, size=%d\n", (void *)aliases,
  778. (aliases == UA_NULL) ? -1 : aliases->size));
  779. s->aliases = aliases;
  780. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL;
  781. } else {
  782. UA_Node* node = (UA_Node*) attr;
  783. DBG(printf("UA_NodeSet_decodeXML - finished node: node=%p\n", (void* )node));
  784. Namespace_insert(dst->ns, node);
  785. DBG(printf("UA_NodeSet_decodeXml - Inserting "));
  786. DBG(print_node(node));
  787. s->parent[s->depth - 1].children[s->parent[s->depth - 1].activeChild].obj = UA_NULL;
  788. }
  789. }
  790. return UA_SUCCESS;
  791. }
  792. /** lookup if element is a known child of parent, if yes go for it otherwise ignore */
  793. void XML_Stack_startElement(void *data, const char *el, const char **attr) {
  794. XML_Stack *s = (XML_Stack *)data;
  795. int i;
  796. // scan expected children
  797. XML_Parent *cp = &s->parent[s->depth];
  798. for(i = 0;i < cp->len;i++) {
  799. if(0 == strncmp(cp->children[i].name, el, cp->children[i].length)) {
  800. DBG_VERBOSE(XML_Stack_print(s));
  801. DBG_VERBOSE(printf("%s - processing\n", el));
  802. cp->activeChild = i;
  803. s->depth++;
  804. s->parent[s->depth].name = el;
  805. s->parent[s->depth].len = 0;
  806. s->parent[s->depth].textAttribIdx = -1;
  807. s->parent[s->depth].activeChild = -1;
  808. // finally call the elementHandler and return
  809. cp->children[i].elementHandler(data, attr, cp->children[i].obj, TRUE);
  810. return;
  811. }
  812. }
  813. // if we come here we rejected the processing of el
  814. DBG_VERBOSE(XML_Stack_print(s));
  815. DBG_VERBOSE(printf("%s - rejected\n", el));
  816. s->depth++;
  817. s->parent[s->depth].name = el;
  818. // this should be sufficient to reject the children as well
  819. s->parent[s->depth].len = 0;
  820. }
  821. UA_Int32 XML_isSpace(cstring s, int len) {
  822. int i;
  823. for(i = 0;i < len;i++) {
  824. if(!isspace(s[i]))
  825. return UA_FALSE;
  826. }
  827. return UA_TRUE;
  828. }
  829. /* gather text */
  830. void XML_Stack_handleText(void * data, const char *txt, int len) {
  831. /* XML_Stack* s = (XML_Stack*) data; */
  832. if (len > 0 && !XML_isSpace(txt, len)) {
  833. /* XML_Parent* cp = &(s->parent[s->depth]); // determine current element */
  834. UA_ByteString src = { len+1, (UA_Byte*) txt };
  835. UA_ByteString *dst;
  836. UA_ByteString_new(&dst); // alloc dst
  837. UA_ByteString_copy(&src,dst); // alloc dst->data and copy txt
  838. dst->data[len] = 0; // add terminating zero to handle single line efficiently
  839. /* UA_list_addPayloadToBack(&(cp->textGatherList), (void*) dst); */
  840. /* if (cp->totalGatherLength == -1) { */
  841. /* cp->totalGatherLength = len; */
  842. /* } else { */
  843. /* cp->totalGatherLength += len; */
  844. /* } */
  845. }
  846. }
  847. char* theGatherBuffer;
  848. void textGatherListTotalLength(void* payload) {
  849. UA_ByteString* b = (UA_ByteString*) payload;
  850. #ifdef DEBUG
  851. UA_ByteString_printf("\t",b);
  852. #endif
  853. UA_memcpy(theGatherBuffer,b->data,b->length-1); // remove trailing zero
  854. theGatherBuffer += (b->length-1);
  855. }
  856. /** if we are an activeChild of a parent we call the child-handler */
  857. void XML_Stack_endElement(void *data, const char *el) {
  858. /* XML_Stack *s = (XML_Stack *)data; */
  859. /* XML_Parent* ce = &(s->parent[s->depth]); */
  860. /* if (ce->textAttribIdx >= 0 && ce->totalGatherLength > 0 ) { */
  861. /* ce->activeChild = ce->textAttribIdx; */
  862. /* char* buf; */
  863. /* if (UA_list_getFirst(&(ce->textGatherList)) == UA_list_getLast(&(ce->textGatherList)) ) { */
  864. /* buf = (char*) ((UA_ByteString*) UA_list_getFirst(&(ce->textGatherList))->payload)->data; */
  865. /* } else { */
  866. /* printf("XML_Stack_endElement - more than one text snippet with total length=%d:\n",ce->totalGatherLength); */
  867. /* UA_alloc((void**)&theGatherBuffer,ce->totalGatherLength+1); */
  868. /* buf = theGatherBuffer; */
  869. /* UA_list_iteratePayload(&(ce->textGatherList), textGatherListTotalLength); */
  870. /* buf[ce->totalGatherLength] = 0; */
  871. /* printf("XML_Stack_endElement - gatherBuffer %s:\n",buf); */
  872. /* } */
  873. /* XML_Attr attr[3] = { ce->textAttrib, buf, UA_NULL }; */
  874. /* DBG(printf("handleText @ %s calls start elementHandler %s with dst=%p, buf={%s}\n", XML_Stack_path(s),ce->children[ce->activeChild].name, ce->children[ce->activeChild].obj, buf)); */
  875. /* ce->children[ce->activeChild].elementHandler(s, attr, ce->children[ce->activeChild].obj, TRUE); */
  876. /* if (s->parent[s->depth-1].activeChild > 0) { */
  877. /* XML_child* c = &(s->parent[s->depth-1].children[s->parent[s->depth-1].activeChild]); */
  878. /* c->elementHandler(s, UA_NULL, c->obj, FALSE); */
  879. /* } */
  880. /* if (UA_list_getFirst(&(ce->textGatherList)) != UA_list_getLast(&(ce->textGatherList)) ) { */
  881. /* UA_free(buf); */
  882. /* } */
  883. /* UA_list_destroy(&(ce->textGatherList),(UA_list_PayloadVisitor) UA_ByteString_delete); */
  884. /* UA_list_init(&(ce->textGatherList)); // don't know if destroy leaves the list in usable state... */
  885. /* ce->totalGatherLength = -1; */
  886. /* } */
  887. /* // the parent of the parent (pop) of the element knows the elementHandler, therefore depth-2! */
  888. /* if (s->depth > 1) { */
  889. /* // inform parents elementHandler that everything is done */
  890. /* XML_Parent *cp = &(s->parent[s->depth - 1]); */
  891. /* XML_Parent *cpp = &(s->parent[s->depth - 2]); */
  892. /* if(cpp->activeChild >= 0 && cp->activeChild >= 0) { */
  893. /* DBG_VERBOSE(XML_Stack_print(s)); */
  894. /* DBG_VERBOSE( */
  895. /* printf(" - inform pop %s, arg=%p\n", cpp->children[cpp->activeChild].name, */
  896. /* (void * )cp->children[cp->activeChild].obj)); */
  897. /* cpp->children[cpp->activeChild].elementHandler(s, (XML_Attr *)cp->children[cp->activeChild].obj, */
  898. /* cpp->children[cpp->activeChild].obj, FALSE); */
  899. /* } */
  900. /* // reset */
  901. /* cp->activeChild = -1; */
  902. /* } */
  903. /* s->depth--; */
  904. }