xml2ns0.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * xml2ns0.c
  3. *
  4. * Created on: 21.04.2014
  5. * Author: mrt
  6. */
  7. #include <expat.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h> // strlen
  11. #include "opcua.h"
  12. typedef char const * const XML_Attr_t;
  13. typedef char const * cstring_t;
  14. struct XML_Stack;
  15. typedef UA_Int32 (*XML_decoder)(struct XML_Stack* s, XML_Attr_t* attr, void* dst);
  16. typedef struct XML_child {
  17. cstring_t name;
  18. UA_Int32 type;
  19. XML_decoder handler;
  20. } XML_child_t;
  21. typedef struct XML_Parent {
  22. cstring_t name;
  23. void* obj;
  24. int textAttribIdx; // -1 - not set
  25. cstring_t textAttrib;
  26. int len; // -1 - empty set
  27. XML_child_t children[20];
  28. } XML_Parent_t;
  29. typedef struct XML_Stack {
  30. int depth;
  31. XML_Parent_t parent[10];
  32. } XML_Stack_t;
  33. void XML_Stack_init(XML_Stack_t* p, cstring_t name) {
  34. unsigned int i,j;
  35. p->depth = 0;
  36. for (i=0;i<10;i++) {
  37. p->parent[i].name = UA_NULL;
  38. p->parent[i].len = 0;
  39. p->parent[i].textAttrib = UA_NULL;
  40. p->parent[i].textAttribIdx = -1;
  41. p->parent[i].obj = UA_NULL;
  42. for (j=0;j<20;j++) {
  43. p->parent[i].children[j].name = UA_NULL;
  44. p->parent[i].children[j].handler = UA_NULL;
  45. p->parent[i].children[j].type = UA_INVALIDTYPE;
  46. }
  47. }
  48. p->parent[0].name = name;
  49. }
  50. // FIXME: we might want to calculate textAttribIdx
  51. void XML_Stack_handleTextAs(XML_Stack_t* p,cstring_t textAttrib, unsigned int textAttribIdx) {
  52. p->parent[p->depth].textAttrib = textAttrib;
  53. p->parent[p->depth].textAttribIdx = textAttribIdx;
  54. }
  55. void XML_Stack_addChildHandler(XML_Stack_t* p,cstring_t name,XML_decoder handler, UA_Int32 type) {
  56. unsigned int len = p->parent[p->depth].len;
  57. p->parent[p->depth].children[len].name = name;
  58. p->parent[p->depth].children[len].handler = handler;
  59. p->parent[p->depth].children[len].type = type;
  60. p->parent[p->depth].len++;
  61. }
  62. UA_Int32 UA_NodeId_copycstring(cstring_t src,UA_NodeId* dst) {
  63. dst->encodingByte = UA_NODEIDTYPE_TWOBYTE;
  64. dst->namespace = 0;
  65. // FIXME: assumes i=nnnn, does not care for aliases as of now
  66. dst->identifier.numeric = atoi(&src[2]);
  67. return UA_SUCCESS;
  68. }
  69. typedef struct T_UA_NodeSet { int dummy; } UA_NodeSet;
  70. UA_Int32 UA_Array_decodeXML(XML_Stack_t* s, XML_Attr_t* attr, void* dst) {
  71. UA_UInt32 i;
  72. return UA_SUCCESS;
  73. }
  74. UA_Int32 UA_Int32_decodeXML(XML_Stack_t* s, XML_Attr_t* attr, UA_Int32* dst) {
  75. UA_UInt32 i;
  76. return UA_SUCCESS;
  77. }
  78. UA_Int32 UA_String_decodeXML(XML_Stack_t* s, XML_Attr_t* attr, UA_String* dst) {
  79. UA_UInt32 i;
  80. if (s->parent[s->depth].len == 0 ) {
  81. XML_Stack_addChildHandler(s,"Data",(XML_decoder)UA_Array_decodeXML, UA_BYTE);
  82. XML_Stack_addChildHandler(s,"Length",(XML_decoder)UA_Int32_decodeXML, UA_INT32);
  83. XML_Stack_handleTextAs(s,"Data",0);
  84. }
  85. return UA_SUCCESS;
  86. }
  87. UA_Int32 UA_LocalizedText_decodeXML(XML_Stack_t* s, XML_Attr_t* attr, UA_LocalizedText* dst) {
  88. UA_UInt32 i;
  89. if (s->parent[s->depth].len == 0 ) {
  90. XML_Stack_addChildHandler(s,"Text",(XML_decoder)UA_String_decodeXML, UA_STRING);
  91. XML_Stack_addChildHandler(s,"Locale",(XML_decoder)UA_String_decodeXML, UA_STRING);
  92. XML_Stack_handleTextAs(s,"Text",0);
  93. }
  94. return UA_SUCCESS;
  95. }
  96. UA_Int32 UA_DataTypeNode_decodeXML(XML_Stack_t* s, XML_Attr_t* attr, UA_DataTypeNode* dst) {
  97. UA_UInt32 i;
  98. if (s->parent[s->depth].len == 0 ) {
  99. XML_Stack_addChildHandler(s,"DisplayName",(XML_decoder)UA_LocalizedText_decodeXML, UA_LOCALIZEDTEXT);
  100. XML_Stack_addChildHandler(s,"Description",(XML_decoder)UA_LocalizedText_decodeXML, UA_LOCALIZEDTEXT);
  101. }
  102. dst->nodeClass = UA_NODECLASS_DATATYPE;
  103. for (i = 0; attr[i]; i += 2) {
  104. if (0==strncmp("NodeId",attr[i],strlen("NodeId"))) {
  105. UA_NodeId_copycstring(attr[i+1],&(dst->nodeId));
  106. } else if (0==strncmp("BrowseName",attr[i],strlen("BrowseName"))) {
  107. UA_String_copycstring(attr[i+1],&(dst->browseName.name));
  108. dst->browseName.namespaceIndex = 0;
  109. } else if (0==strncmp("DisplayName",attr[i],strlen("DisplayName"))) {
  110. UA_String_copycstring(attr[i+1],&(dst->displayName.text));
  111. dst->displayName.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
  112. } else if (0==strncmp("Description",attr[i],strlen("Description"))) {
  113. UA_String_copycstring(attr[i+1],&(dst->description.text));
  114. dst->description.encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
  115. }
  116. }
  117. return UA_SUCCESS;
  118. }
  119. UA_Int32 UA_NodeSet_decodeXML(XML_Stack_t* s, XML_Attr_t* attr, UA_NodeSet* dst) {
  120. if (s->parent[s->depth].len == 0 ) {
  121. XML_Stack_addChildHandler(s,"UADataType",(XML_decoder)UA_DataTypeNode_decodeXML, UA_DATATYPENODE);
  122. }
  123. return UA_SUCCESS;
  124. }
  125. void startElement(void * data, const char *el, const char **attr) {
  126. XML_Stack_t* p = (XML_Stack_t*) data;
  127. int i, j;
  128. // scan expected children
  129. for (i = 0; i < p->parent[p->depth].len; i++) {
  130. if (0 == strncmp(p->parent[p->depth].children[i].name,el,strlen(p->parent[p->depth].children[i].name))) {
  131. printf("processing child ");
  132. for (j=0;j<=p->depth;j++) {
  133. printf("%s.",p->parent[j].name);
  134. }
  135. printf("%s\n",el);
  136. // create the object
  137. void* obj;
  138. UA_[p->parent[p->depth].children[i].type].new(&obj);
  139. // increment depth
  140. p->depth++;
  141. p->parent[p->depth].name = el;
  142. p->parent[p->depth].len = 0;
  143. p->parent[p->depth].textAttribIdx = -1;
  144. p->parent[p->depth].obj = obj;
  145. // call the handler and return
  146. p->parent[p->depth-1].children[i].handler(data,attr,obj);
  147. return;
  148. }
  149. }
  150. // if we come here we rejected the processing of el
  151. printf("rejected processing of unexpected child ");
  152. for (i=0;i<=p->depth;i++) {
  153. printf("%s.",p->parent[i].name);
  154. }
  155. printf("%s\n",el);
  156. p->depth++;
  157. p->parent[p->depth].name = el;
  158. // this should be sufficient to reject the children as well
  159. p->parent[p->depth].len = 0;
  160. } /* End of start handler */
  161. UA_Int32 XML_isSpace(cstring_t s, int len) {
  162. UA_Int32 retval = UA_TRUE;
  163. int i;
  164. for (i=0; i<len; i++) {
  165. if (! isspace(s[i])) {
  166. return UA_FALSE;
  167. }
  168. }
  169. return UA_TRUE;
  170. }
  171. void handleText(void * data, const char *s, int len) {
  172. XML_Stack_t* p = (XML_Stack_t*) data;
  173. int j, i;
  174. if (len > 0 && ! XML_isSpace(s,len)) {
  175. XML_Parent_t* cp = &(p->parent[p->depth]);
  176. if (cp->textAttribIdx >= 0) {
  177. int childIdx = cp->textAttribIdx;
  178. XML_Attr_t attr[2] = { cp->textAttrib, s };
  179. cp->children[childIdx].handler(p,attr,cp->obj);
  180. }
  181. }
  182. } /* End of text handler */
  183. void endElement(void *data, const char *el) {
  184. XML_Stack_t* p = (XML_Stack_t*) data;
  185. p->depth--;
  186. } /* End of end handler */
  187. int main()
  188. {
  189. char buf[1024];
  190. int len; /* len is the number of bytes in the current bufferful of data */
  191. int done;
  192. XML_Stack_t p;
  193. XML_Stack_init(&p, "ROOT");
  194. XML_Stack_addChildHandler(&p,"UANodeSet", (XML_decoder) UA_NodeSet_decodeXML, UA_INVALIDTYPE);
  195. XML_Parser parser = XML_ParserCreate(NULL);
  196. XML_SetUserData(parser, &p);
  197. XML_SetElementHandler(parser, startElement, endElement);
  198. XML_SetCharacterDataHandler(parser, handleText);
  199. while ((len = read(0,buf,1024)) > 0) {
  200. if (!XML_Parse(parser, buf, len, (len<1024))) {
  201. return 1;
  202. }
  203. }
  204. XML_ParserFree(parser);
  205. return 0;
  206. }