ua_types.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. #include <stdio.h> // printf
  2. #include <stdlib.h> // alloc, free, vsnprintf
  3. #include <string.h>
  4. #include <stdarg.h> // va_start, va_end
  5. #include <time.h>
  6. #include <sys/time.h>
  7. #include "util/ua_util.h"
  8. #include "ua_types.h"
  9. #include "ua_types_encoding_binary.h"
  10. #include "ua_namespace_0.h"
  11. #include "inttypes.h"
  12. /************/
  13. /* Built-In */
  14. /************/
  15. /* Boolean */
  16. UA_Int32 UA_Boolean_init(UA_Boolean *p) {
  17. if(p == UA_NULL) return UA_ERROR;
  18. *p = UA_FALSE;
  19. return UA_SUCCESS;
  20. }
  21. UA_TYPE_DELETE_DEFAULT(UA_Boolean)
  22. UA_TYPE_DELETEMEMBERS_NOACTION(UA_Boolean)
  23. UA_TYPE_NEW_DEFAULT(UA_Boolean)
  24. UA_TYPE_COPY_DEFAULT(UA_Boolean)
  25. #ifdef DEBUG
  26. void UA_Boolean_print(const UA_Boolean *p, FILE *stream) {
  27. if(p == UA_NULL || stream == UA_NULL) return;
  28. if(*p) fprintf(stream, "UA_TRUE");
  29. else fprintf(stream, "UA_FALSE");
  30. }
  31. #endif
  32. /* SByte */
  33. UA_TYPE_DEFAULT(UA_SByte)
  34. #ifdef DEBUG
  35. void UA_SByte_print(const UA_SByte *p, FILE *stream) {
  36. if(p == UA_NULL || stream == UA_NULL) return;
  37. UA_SByte x = *p;
  38. fprintf(stream, "%s%x\n", x<0?"-":"", x<0?-x:x);
  39. }
  40. #endif
  41. /* Byte */
  42. UA_TYPE_DEFAULT(UA_Byte)
  43. #ifdef DEBUG
  44. void UA_Byte_print(const UA_Byte *p, FILE *stream) {
  45. if(p == UA_NULL || stream == UA_NULL) return;
  46. fprintf(stream, "%x", *p);
  47. }
  48. #endif
  49. /* Int16 */
  50. UA_TYPE_DEFAULT(UA_Int16)
  51. #ifdef DEBUG
  52. void UA_Int16_print(const UA_Int16 *p, FILE *stream) {
  53. if(p == UA_NULL || stream == UA_NULL) return;
  54. fprintf(stream, "%d", *p);
  55. }
  56. #endif
  57. /* UInt16 */
  58. UA_TYPE_DEFAULT(UA_UInt16)
  59. #ifdef DEBUG
  60. void UA_UInt16_print(const UA_UInt16 *p, FILE *stream) {
  61. if(p == UA_NULL || stream == UA_NULL) return;
  62. fprintf(stream, "%u", *p);
  63. }
  64. #endif
  65. /* Int32 */
  66. UA_TYPE_DEFAULT(UA_Int32)
  67. #ifdef DEBUG
  68. void UA_Int32_print(const UA_Int32 *p, FILE *stream) {
  69. if(p == UA_NULL || stream == UA_NULL) return;
  70. fprintf(stream, "%d", *p);
  71. }
  72. #endif
  73. /* UInt32 */
  74. UA_TYPE_DEFAULT(UA_UInt32)
  75. #ifdef DEBUG
  76. void UA_UInt32_print(const UA_UInt32 *p, FILE *stream) {
  77. if(p == UA_NULL || stream == UA_NULL) return;
  78. fprintf(stream, "%u", *p);
  79. }
  80. #endif
  81. /* Int64 */
  82. UA_TYPE_DEFAULT(UA_Int64)
  83. #ifdef DEBUG
  84. void UA_Int64_print(const UA_Int64 *p, FILE *stream) {
  85. if(p == UA_NULL || stream == UA_NULL) return;
  86. fprintf(stream, "%" PRIi64, *p);
  87. }
  88. #endif
  89. /* UInt64 */
  90. UA_TYPE_DEFAULT(UA_UInt64)
  91. #ifdef DEBUG
  92. void UA_UInt64_print(const UA_UInt64 *p, FILE *stream) {
  93. if(p == UA_NULL || stream == UA_NULL) return;
  94. fprintf(stream, "%" PRIu64, *p);
  95. }
  96. #endif
  97. /* Float */
  98. UA_TYPE_DEFAULT(UA_Float)
  99. #ifdef DEBUG
  100. void UA_Float_print(const UA_Float *p, FILE *stream) {
  101. if(p == UA_NULL || stream == UA_NULL) return;
  102. fprintf(stream, "%f", *p);
  103. }
  104. #endif
  105. /* Double */
  106. UA_TYPE_DEFAULT(UA_Double)
  107. #ifdef DEBUG
  108. void UA_Double_print(const UA_Double *p, FILE *stream) {
  109. if(p == UA_NULL || stream == UA_NULL) return;
  110. fprintf(stream, "%f", *p);
  111. }
  112. #endif
  113. /* String */
  114. UA_TYPE_NEW_DEFAULT(UA_String)
  115. UA_Int32 UA_String_init(UA_String *p) {
  116. if(p == UA_NULL) return UA_ERROR;
  117. p->length = -1;
  118. p->data = UA_NULL;
  119. return UA_SUCCESS;
  120. }
  121. UA_TYPE_DELETE_DEFAULT(UA_String)
  122. UA_Int32 UA_String_deleteMembers(UA_String *p) {
  123. UA_Int32 retval = UA_SUCCESS;
  124. if(p != UA_NULL && p->length > 0 && p->data != UA_NULL) {
  125. retval |= UA_free(p->data);
  126. retval |= UA_String_init(p);
  127. }
  128. return retval;
  129. }
  130. UA_Int32 UA_String_copy(UA_String const *src, UA_String *dst) {
  131. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  132. UA_Int32 retval = UA_SUCCESS;
  133. dst->data = UA_NULL;
  134. dst->length = -1;
  135. if(src->length > 0) {
  136. retval |= UA_alloc((void **)&dst->data, src->length);
  137. if(retval == UA_SUCCESS) {
  138. retval |= UA_memcpy((void *)dst->data, src->data, src->length);
  139. dst->length = src->length;
  140. }
  141. }
  142. return retval;
  143. }
  144. #ifdef DEBUG
  145. void UA_String_print(const UA_String *p, FILE *stream) {
  146. if(p == UA_NULL || stream == UA_NULL) return;
  147. fprintf(stream, "(UA_String){%d,", p->length);
  148. if(p->data != UA_NULL)
  149. fprintf(stream, "\"%.*s\"}", p->length, p->data);
  150. else
  151. fprintf(stream, "UA_NULL}");
  152. }
  153. #endif
  154. UA_Int32 UA_String_copycstring(char const *src, UA_String *dst) {
  155. UA_Int32 retval = UA_SUCCESS;
  156. dst->length = strlen(src);
  157. dst->data = UA_NULL;
  158. if(dst->length > 0) {
  159. retval |= UA_alloc((void **)&dst->data, dst->length);
  160. if(retval == UA_SUCCESS)
  161. retval |= UA_memcpy((void *)dst->data, src, dst->length);
  162. }
  163. return retval;
  164. }
  165. #define UA_STRING_COPYPRINTF_BUFSIZE 1024
  166. UA_Int32 UA_String_copyprintf(char const *fmt, UA_String *dst, ...) {
  167. UA_Int32 retval = UA_SUCCESS;
  168. char src[UA_STRING_COPYPRINTF_BUFSIZE];
  169. UA_Int32 len;
  170. va_list ap;
  171. va_start(ap, dst);
  172. #pragma GCC diagnostic push
  173. #pragma GCC diagnostic ignored "-Wformat-nonliteral"
  174. // vsnprintf should only take a literal and no variable to be secure
  175. len = vsnprintf(src, UA_STRING_COPYPRINTF_BUFSIZE, fmt, ap);
  176. #pragma GCC diagnostic pop
  177. va_end(ap);
  178. if(len < 0) { // FIXME: old glibc 2.0 would return -1 when truncated
  179. dst->length = 0;
  180. dst->data = UA_NULL;
  181. retval = UA_ERR_INVALID_VALUE;
  182. } else {
  183. // since glibc 2.1 vsnprintf returns len that would have resulted if buf were large enough
  184. dst->length = ( len > UA_STRING_COPYPRINTF_BUFSIZE ? UA_STRING_COPYPRINTF_BUFSIZE : len );
  185. retval |= UA_alloc((void **)&dst->data, dst->length);
  186. if(retval == UA_SUCCESS)
  187. retval |= UA_memcpy((void *)dst->data, src, dst->length);
  188. }
  189. return retval;
  190. }
  191. UA_Int32 UA_String_equal(const UA_String *string1, const UA_String *string2) {
  192. UA_Int32 retval;
  193. if(string1->length == 0 && string2->length == 0)
  194. retval = UA_EQUAL;
  195. else if(string1->length == -1 && string2->length == -1)
  196. retval = UA_EQUAL;
  197. else if(string1->length != string2->length)
  198. retval = UA_NOT_EQUAL;
  199. else {
  200. // casts are needed to overcome signed warnings
  201. UA_Int32 is = strncmp((char const *)string1->data, (char const *)string2->data, string1->length);
  202. retval = (is == 0) ? UA_EQUAL : UA_NOT_EQUAL;
  203. }
  204. return retval;
  205. }
  206. #ifdef DEBUG
  207. void UA_String_printf(char const *label, const UA_String *string) {
  208. printf("%s {Length=%d, Data=%.*s}\n", label, string->length,
  209. string->length, (char *)string->data);
  210. }
  211. #endif
  212. #ifdef DEBUG
  213. void UA_String_printx(char const *label, const UA_String *string) {
  214. if(string == UA_NULL) {
  215. printf("%s {NULL}\n", label); return;
  216. }
  217. printf("%s {Length=%d, Data=", label, string->length);
  218. if(string->length > 0) {
  219. for(UA_Int32 i = 0;i < string->length;i++) {
  220. printf("%c%d", i == 0 ? '{' : ',', (string->data)[i]);
  221. // if (i > 0 && !(i%20)) { printf("\n\t"); }
  222. }
  223. } else
  224. printf("{");
  225. printf("}}\n");
  226. }
  227. #endif
  228. #ifdef DEBUG
  229. void UA_String_printx_hex(char const *label, const UA_String *string) {
  230. printf("%s {Length=%d, Data=", label, string->length);
  231. if(string->length > 0) {
  232. for(UA_Int32 i = 0;i < string->length;i++)
  233. printf("%c%x", i == 0 ? '{' : ',', (string->data)[i]);
  234. } else
  235. printf("{");
  236. printf("}}\n");
  237. }
  238. #endif
  239. /* DateTime */
  240. UA_TYPE_AS(UA_DateTime, UA_Int64)
  241. // Number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
  242. #define FILETIME_UNIXTIME_BIAS_SEC 11644473600LL
  243. // Factors
  244. #define HUNDRED_NANOSEC_PER_USEC 10LL
  245. #define HUNDRED_NANOSEC_PER_SEC (HUNDRED_NANOSEC_PER_USEC * 1000000LL)
  246. // IEC 62541-6 §5.2.2.5 A DateTime value shall be encoded as a 64-bit signed integer
  247. // which represents the number of 100 nanosecond intervals since January 1, 1601 (UTC).
  248. UA_DateTime UA_DateTime_now() {
  249. UA_DateTime dateTime;
  250. struct timeval tv;
  251. gettimeofday(&tv, UA_NULL);
  252. dateTime = (tv.tv_sec + FILETIME_UNIXTIME_BIAS_SEC)
  253. * HUNDRED_NANOSEC_PER_SEC + tv.tv_usec * HUNDRED_NANOSEC_PER_USEC;
  254. return dateTime;
  255. }
  256. UA_DateTimeStruct UA_DateTime_toStruct(UA_DateTime time) {
  257. UA_DateTimeStruct dateTimeStruct;
  258. //calcualting the the milli-, micro- and nanoseconds
  259. UA_DateTime timeTemp;
  260. timeTemp = (time-((time/10)*10))*100; //getting the last digit -> *100 for the 100 nanaseconds resolution
  261. dateTimeStruct.nanoSec = timeTemp; //123 456 7 -> 700 nanosec;
  262. timeTemp = (time-((time/10000)*10000))/10;
  263. dateTimeStruct.microSec = timeTemp; //123 456 7 -> 456 microsec
  264. timeTemp = (time-((time/10000000)*10000000))/10000;
  265. dateTimeStruct.milliSec = timeTemp; //123 456 7 -> 123 millisec
  266. //calculating the unix time with #include <time.h>
  267. time_t timeInSec = time/10000000; //converting the nanoseconds time in unixtime
  268. struct tm ts;
  269. ts = *gmtime(&timeInSec);
  270. //strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);
  271. //printf("%s\n", buf);
  272. dateTimeStruct.sec = ts.tm_sec;
  273. dateTimeStruct.min = ts.tm_min;
  274. dateTimeStruct.hour = ts.tm_hour;
  275. dateTimeStruct.day = ts.tm_mday;
  276. dateTimeStruct.mounth = ts.tm_mon+1;
  277. dateTimeStruct.year = ts.tm_year + 1900;
  278. return dateTimeStruct;
  279. }
  280. UA_Int32 UA_DateTime_toString(UA_DateTime time, UA_String *timeString) {
  281. char *charBuf = (char *)(*timeString).data;
  282. UA_DateTimeStruct tSt = UA_DateTime_toStruct(time);
  283. sprintf(charBuf, "%2d/%2d/%4d %2d:%2d:%2d.%3d.%3d.%3d", tSt.mounth, tSt.day, tSt.year,
  284. tSt.hour, tSt.min, tSt.sec, tSt.milliSec, tSt.microSec, tSt.nanoSec);
  285. return UA_SUCCESS;
  286. }
  287. /* Guid */
  288. UA_TYPE_DELETE_DEFAULT(UA_Guid)
  289. UA_Int32 UA_Guid_deleteMembers(UA_Guid *p) {
  290. return UA_SUCCESS;
  291. }
  292. UA_Int32 UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2) {
  293. return memcmp(g1, g2, sizeof(UA_Guid));
  294. }
  295. UA_Int32 UA_Guid_init(UA_Guid *p) {
  296. if(p == UA_NULL) return UA_ERROR;
  297. p->data1 = 0;
  298. p->data2 = 0;
  299. p->data3 = 0;
  300. memset(p->data4, 0, sizeof(UA_Byte)*8);
  301. return UA_SUCCESS;
  302. }
  303. UA_TYPE_NEW_DEFAULT(UA_Guid)
  304. UA_Int32 UA_Guid_copy(UA_Guid const *src, UA_Guid *dst) {
  305. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  306. UA_Int32 retval = UA_SUCCESS;
  307. retval |= UA_memcpy((void *)dst, (void *)src, sizeof(UA_Guid));
  308. return retval;
  309. }
  310. #ifdef DEBUG
  311. void UA_Guid_print(const UA_Guid *p, FILE *stream) {
  312. if(p == UA_NULL || stream == UA_NULL) return;
  313. fprintf(stream, "(UA_Guid){%u, %u %u {%x,%x,%x,%x,%x,%x,%x,%x}}", p->data1, p->data2, p->data3, p->data4[0],
  314. p->data4[1], p->data4[2], p->data4[3], p->data4[4], p->data4[5], p->data4[6], p->data4[7]);
  315. }
  316. #endif
  317. /* ByteString */
  318. UA_TYPE_AS(UA_ByteString, UA_String)
  319. UA_Int32 UA_ByteString_equal(const UA_ByteString *string1, const UA_ByteString *string2) {
  320. return UA_String_equal((const UA_String *)string1, (const UA_String *)string2);
  321. }
  322. #ifdef DEBUG
  323. void UA_ByteString_printf(char *label, const UA_ByteString *string) {
  324. UA_String_printf(label, (UA_String *)string);
  325. }
  326. #endif
  327. #ifdef DEBUG
  328. void UA_ByteString_printx(char *label, const UA_ByteString *string) {
  329. UA_String_printx(label, (UA_String *)string);
  330. }
  331. #endif
  332. #ifdef DEBUG
  333. void UA_ByteString_printx_hex(char *label, const UA_ByteString *string) {
  334. UA_String_printx_hex(label, (UA_String *)string);
  335. }
  336. #endif
  337. UA_Byte UA_Byte_securityPoliceNoneData[] = "http://opcfoundation.org/UA/SecurityPolicy#None";
  338. // sizeof()-1 : discard the implicit null-terminator of the c-char-string
  339. UA_ByteString UA_ByteString_securityPoliceNone = { sizeof(UA_Byte_securityPoliceNoneData)-1, UA_Byte_securityPoliceNoneData };
  340. UA_Int32 UA_ByteString_newMembers(UA_ByteString *p, UA_Int32 length) {
  341. UA_Int32 retval = UA_SUCCESS;
  342. if((retval |= UA_alloc((void **)&p->data, length)) == UA_SUCCESS)
  343. p->length = length;
  344. else {
  345. p->length = -1;
  346. p->data = UA_NULL;
  347. }
  348. return retval;
  349. }
  350. /* XmlElement */
  351. UA_TYPE_AS(UA_XmlElement, UA_ByteString)
  352. /* NodeId */
  353. UA_Int32 UA_NodeId_init(UA_NodeId *p) {
  354. if(p == UA_NULL) return UA_ERROR;
  355. p->encodingByte = UA_NODEIDTYPE_TWOBYTE;
  356. p->namespace = 0;
  357. memset(&p->identifier, 0, sizeof(p->identifier));
  358. return UA_SUCCESS;
  359. }
  360. UA_TYPE_NEW_DEFAULT(UA_NodeId)
  361. UA_Int32 UA_NodeId_copy(UA_NodeId const *src, UA_NodeId *dst) {
  362. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  363. UA_Int32 retval = UA_SUCCESS;
  364. retval |= UA_Byte_copy(&src->encodingByte, &dst->encodingByte);
  365. switch(src->encodingByte & UA_NODEIDTYPE_MASK) {
  366. case UA_NODEIDTYPE_TWOBYTE:
  367. case UA_NODEIDTYPE_FOURBYTE:
  368. case UA_NODEIDTYPE_NUMERIC:
  369. // nothing to do
  370. retval |= UA_UInt16_copy(&src->namespace, &dst->namespace);
  371. retval |= UA_UInt32_copy(&src->identifier.numeric, &dst->identifier.numeric);
  372. break;
  373. case UA_NODEIDTYPE_STRING: // Table 6, second entry
  374. retval |= UA_String_copy(&src->identifier.string, &dst->identifier.string);
  375. break;
  376. case UA_NODEIDTYPE_GUID: // Table 6, third entry
  377. retval |= UA_Guid_copy(&src->identifier.guid, &dst->identifier.guid);
  378. break;
  379. case UA_NODEIDTYPE_BYTESTRING: // Table 6, "OPAQUE"
  380. retval |= UA_ByteString_copy(&src->identifier.byteString, &dst->identifier.byteString);
  381. break;
  382. }
  383. return retval;
  384. }
  385. UA_Boolean UA_NodeId_isBasicType(UA_NodeId const *id) {
  386. return (id->namespace == 0 && id->identifier.numeric <= UA_DIAGNOSTICINFO);
  387. }
  388. UA_TYPE_DELETE_DEFAULT(UA_NodeId)
  389. UA_Int32 UA_NodeId_deleteMembers(UA_NodeId *p) {
  390. UA_Int32 retval = UA_SUCCESS;
  391. if(p == UA_NULL) return retval;
  392. switch(p->encodingByte & UA_NODEIDTYPE_MASK) {
  393. case UA_NODEIDTYPE_TWOBYTE:
  394. case UA_NODEIDTYPE_FOURBYTE:
  395. case UA_NODEIDTYPE_NUMERIC:
  396. // nothing to do
  397. break;
  398. case UA_NODEIDTYPE_STRING: // Table 6, second entry
  399. retval |= UA_String_deleteMembers(&p->identifier.string);
  400. break;
  401. case UA_NODEIDTYPE_GUID: // Table 6, third entry
  402. retval |= UA_Guid_deleteMembers(&p->identifier.guid);
  403. break;
  404. case UA_NODEIDTYPE_BYTESTRING: // Table 6, "OPAQUE"
  405. retval |= UA_ByteString_deleteMembers(&p->identifier.byteString);
  406. break;
  407. }
  408. return retval;
  409. }
  410. #ifdef DEBUG
  411. void UA_NodeId_print(const UA_NodeId *p, FILE *stream) {
  412. if(p == UA_NULL || stream == UA_NULL) return;
  413. fprintf(stream, "(UA_NodeId){");
  414. switch(p->encodingByte & UA_NODEIDTYPE_MASK) {
  415. case UA_NODEIDTYPE_TWOBYTE:
  416. fprintf(stream, "UA_NODEIDTYPE_TWOBYTE");
  417. break;
  418. case UA_NODEIDTYPE_FOURBYTE:
  419. fprintf(stream, "UA_NODEIDTYPE_FOURBYTE");
  420. break;
  421. case UA_NODEIDTYPE_NUMERIC:
  422. fprintf(stream, "UA_NODEIDTYPE_NUMERIC");
  423. break;
  424. case UA_NODEIDTYPE_STRING:
  425. fprintf(stream, "UA_NODEIDTYPE_STRING");
  426. break;
  427. case UA_NODEIDTYPE_BYTESTRING:
  428. fprintf(stream, "UA_NODEIDTYPE_BYTESTRING");
  429. break;
  430. case UA_NODEIDTYPE_GUID:
  431. fprintf(stream, "UA_NODEIDTYPE_GUID");
  432. break;
  433. default:
  434. fprintf(stream, "ERROR");
  435. break;
  436. }
  437. fprintf(stream,",%u,", p->namespace);
  438. switch(p->encodingByte & UA_NODEIDTYPE_MASK) {
  439. case UA_NODEIDTYPE_TWOBYTE:
  440. case UA_NODEIDTYPE_FOURBYTE:
  441. case UA_NODEIDTYPE_NUMERIC:
  442. fprintf(stream, ".identifier.numeric=%u", p->identifier.numeric);
  443. break;
  444. case UA_NODEIDTYPE_STRING:
  445. fprintf(stream, ".identifier.string=%.*s", p->identifier.string.length, p->identifier.string.data);
  446. break;
  447. case UA_NODEIDTYPE_BYTESTRING:
  448. fprintf(stream, ".identifier.byteString=%.*s", p->identifier.byteString.length, p->identifier.byteString.data);
  449. break;
  450. case UA_NODEIDTYPE_GUID:
  451. fprintf(stream, ".identifer.guid=");
  452. UA_Guid_print(&p->identifier.guid, stream);
  453. break;
  454. default:
  455. fprintf(stream, "ERROR");
  456. break;
  457. }
  458. fprintf(stream, "}");
  459. }
  460. #endif
  461. #ifdef DEBUG
  462. void UA_NodeId_printf(char *label, const UA_NodeId *node) {
  463. UA_Int32 l;
  464. printf("%s {encodingByte=%d, namespace=%d,", label, (int)( node->encodingByte), (int)(node->namespace));
  465. switch(node->encodingByte & UA_NODEIDTYPE_MASK) {
  466. case UA_NODEIDTYPE_TWOBYTE:
  467. case UA_NODEIDTYPE_FOURBYTE:
  468. case UA_NODEIDTYPE_NUMERIC:
  469. printf("identifier=%d\n", node->identifier.numeric);
  470. break;
  471. case UA_NODEIDTYPE_STRING:
  472. l = ( node->identifier.string.length < 0 ) ? 0 : node->identifier.string.length;
  473. printf("identifier={length=%d, data=%.*s}",
  474. node->identifier.string.length, l,
  475. (char *)(node->identifier.string.data));
  476. break;
  477. case UA_NODEIDTYPE_BYTESTRING:
  478. l = ( node->identifier.byteString.length < 0 ) ? 0 : node->identifier.byteString.length;
  479. printf("identifier={Length=%d, data=%.*s}",
  480. node->identifier.byteString.length, l,
  481. (char *)(node->identifier.byteString.data));
  482. break;
  483. case UA_NODEIDTYPE_GUID:
  484. printf(
  485. "guid={data1=%d, data2=%d, data3=%d, data4={length=%d, data=%.*s}}",
  486. node->identifier.guid.data1, node->identifier.guid.data2,
  487. node->identifier.guid.data3, 8,
  488. 8,
  489. (char *)(node->identifier.guid.data4));
  490. break;
  491. default:
  492. printf("ups! shit happens");
  493. break;
  494. }
  495. printf("}\n");
  496. }
  497. #endif
  498. UA_Int32 UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
  499. if(n1 == UA_NULL || n2 == UA_NULL || n1->namespace != n2->namespace)
  500. return UA_NOT_EQUAL;
  501. switch(n1->encodingByte & UA_NODEIDTYPE_MASK) {
  502. case UA_NODEIDTYPE_TWOBYTE:
  503. case UA_NODEIDTYPE_FOURBYTE:
  504. case UA_NODEIDTYPE_NUMERIC:
  505. if(n1->identifier.numeric == n2->identifier.numeric)
  506. return UA_EQUAL;
  507. else
  508. return UA_NOT_EQUAL;
  509. case UA_NODEIDTYPE_STRING:
  510. return UA_String_equal(&n1->identifier.string, &n2->identifier.string);
  511. case UA_NODEIDTYPE_GUID:
  512. return UA_Guid_equal(&n1->identifier.guid, &n2->identifier.guid);
  513. case UA_NODEIDTYPE_BYTESTRING:
  514. return UA_ByteString_equal(&n1->identifier.byteString, &n2->identifier.byteString);
  515. }
  516. return UA_NOT_EQUAL;
  517. }
  518. UA_Boolean UA_NodeId_isNull(const UA_NodeId *p) {
  519. switch(p->encodingByte & UA_NODEIDTYPE_MASK) {
  520. case UA_NODEIDTYPE_TWOBYTE:
  521. if(p->identifier.numeric != 0) return UA_FALSE;
  522. break;
  523. case UA_NODEIDTYPE_FOURBYTE:
  524. case UA_NODEIDTYPE_NUMERIC:
  525. if(p->namespace != 0 || p->identifier.numeric != 0) return UA_FALSE;
  526. break;
  527. case UA_NODEIDTYPE_STRING:
  528. if(p->namespace != 0 || p->identifier.string.length != 0) return UA_FALSE;
  529. break;
  530. case UA_NODEIDTYPE_GUID:
  531. if(p->namespace != 0 ||
  532. memcmp(&p->identifier.guid, (char[sizeof(UA_Guid)]) { 0 }, sizeof(UA_Guid)) != 0) return UA_FALSE;
  533. break;
  534. case UA_NODEIDTYPE_BYTESTRING:
  535. if(p->namespace != 0 || p->identifier.byteString.length != 0) return UA_FALSE;
  536. break;
  537. default:
  538. return UA_FALSE;
  539. }
  540. return UA_TRUE;
  541. }
  542. /* ExpandedNodeId */
  543. UA_TYPE_DELETE_DEFAULT(UA_ExpandedNodeId)
  544. UA_Int32 UA_ExpandedNodeId_deleteMembers(UA_ExpandedNodeId *p) {
  545. UA_Int32 retval = UA_SUCCESS;
  546. if(p == UA_NULL) return retval;
  547. retval |= UA_NodeId_deleteMembers(&p->nodeId);
  548. retval |= UA_String_deleteMembers(&p->namespaceUri);
  549. return retval;
  550. }
  551. UA_Int32 UA_ExpandedNodeId_init(UA_ExpandedNodeId *p) {
  552. if(p == UA_NULL) return UA_ERROR;
  553. UA_NodeId_init(&p->nodeId);
  554. UA_String_init(&p->namespaceUri);
  555. p->serverIndex = 0;
  556. return UA_SUCCESS;
  557. }
  558. UA_TYPE_NEW_DEFAULT(UA_ExpandedNodeId)
  559. UA_Int32 UA_ExpandedNodeId_copy(UA_ExpandedNodeId const *src, UA_ExpandedNodeId *dst) {
  560. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  561. UA_Int32 retval = UA_SUCCESS;
  562. UA_String_copy(&src->namespaceUri, &dst->namespaceUri);
  563. UA_NodeId_copy(&src->nodeId, &dst->nodeId);
  564. UA_UInt32_copy(&src->serverIndex, &dst->serverIndex);
  565. return retval;
  566. }
  567. #ifdef DEBUG
  568. void UA_ExpandedNodeId_print(const UA_ExpandedNodeId *p, FILE *stream) {
  569. if(p == UA_NULL || stream == UA_NULL) return;
  570. fprintf(stream, "(UA_ExpandedNodeId){");
  571. UA_NodeId_print(&p->nodeId, stream);
  572. fprintf(stream, ",");
  573. UA_String_print(&p->namespaceUri, stream);
  574. fprintf(stream, ",");
  575. UA_UInt32_print(&p->serverIndex, stream);
  576. fprintf(stream, "}");
  577. }
  578. #endif
  579. UA_Boolean UA_ExpandedNodeId_isNull(const UA_ExpandedNodeId *p) {
  580. return UA_NodeId_isNull(&p->nodeId);
  581. }
  582. /* StatusCode */
  583. UA_TYPE_AS(UA_StatusCode, UA_UInt32)
  584. /* QualifiedName */
  585. UA_TYPE_DELETE_DEFAULT(UA_QualifiedName)
  586. UA_Int32 UA_QualifiedName_deleteMembers(UA_QualifiedName *p) {
  587. UA_Int32 retval = UA_SUCCESS;
  588. if(p == UA_NULL) return retval;
  589. retval |= UA_String_deleteMembers(&p->name);
  590. return retval;
  591. }
  592. UA_Int32 UA_QualifiedName_init(UA_QualifiedName *p) {
  593. if(p == UA_NULL) return UA_ERROR;
  594. UA_String_init(&p->name);
  595. p->namespaceIndex = 0;
  596. return UA_SUCCESS;
  597. }
  598. UA_TYPE_NEW_DEFAULT(UA_QualifiedName)
  599. UA_Int32 UA_QualifiedName_copy(UA_QualifiedName const *src, UA_QualifiedName *dst) {
  600. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  601. UA_Int32 retval = UA_SUCCESS;
  602. retval |= UA_String_copy(&src->name, &dst->name);
  603. retval |= UA_UInt16_copy(&src->namespaceIndex, &dst->namespaceIndex);
  604. return retval;
  605. }
  606. #ifdef DEBUG
  607. void UA_QualifiedName_print(const UA_QualifiedName *p, FILE *stream) {
  608. if(p == UA_NULL || stream == UA_NULL) return;
  609. fprintf(stream, "(UA_QualifiedName){");
  610. UA_UInt16_print(&p->namespaceIndex, stream);
  611. fprintf(stream, ",");
  612. UA_String_print(&p->name, stream);
  613. fprintf(stream, "}");
  614. }
  615. #endif
  616. #ifdef DEBUG
  617. void UA_QualifiedName_printf(char const *label, const UA_QualifiedName *qn) {
  618. printf("%s {NamespaceIndex=%u, Length=%d, Data=%.*s}\n", label, qn->namespaceIndex,
  619. qn->name.length, qn->name.length, (char *)qn->name.data);
  620. }
  621. #endif
  622. /* LocalizedText */
  623. UA_TYPE_DELETE_DEFAULT(UA_LocalizedText)
  624. UA_Int32 UA_LocalizedText_deleteMembers(UA_LocalizedText *p) {
  625. if(p == UA_NULL) return UA_SUCCESS;
  626. UA_Int32 retval = UA_SUCCESS;
  627. retval |= UA_String_deleteMembers(&p->locale);
  628. retval |= UA_String_deleteMembers(&p->text);
  629. return retval;
  630. }
  631. UA_Int32 UA_LocalizedText_init(UA_LocalizedText *p) {
  632. if(p == UA_NULL) return UA_ERROR;
  633. UA_String_init(&p->locale);
  634. UA_String_init(&p->text);
  635. return UA_SUCCESS;
  636. }
  637. UA_TYPE_NEW_DEFAULT(UA_LocalizedText)
  638. UA_Int32 UA_LocalizedText_copycstring(char const *src, UA_LocalizedText *dst) {
  639. if(dst == UA_NULL) return UA_ERROR;
  640. UA_LocalizedText_init(dst);
  641. UA_Int32 retval = UA_SUCCESS;
  642. retval |= UA_String_copycstring("EN", &dst->locale); // TODO: Are language codes upper case?
  643. if(retval != UA_SUCCESS) return retval;
  644. retval |= UA_String_copycstring(src, &dst->text);
  645. return retval;
  646. }
  647. UA_Int32 UA_LocalizedText_copy(UA_LocalizedText const *src, UA_LocalizedText *dst) {
  648. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  649. UA_Int32 retval = UA_SUCCESS;
  650. retval |= UA_LocalizedText_init(dst);
  651. retval |= UA_String_copy(&src->locale, &dst->locale);
  652. if(retval != UA_SUCCESS) return retval;
  653. retval |= UA_String_copy(&src->text, &dst->text);
  654. return retval;
  655. }
  656. #ifdef DEBUG
  657. void UA_LocalizedText_print(const UA_LocalizedText *p, FILE *stream) {
  658. if(p == UA_NULL || stream == UA_NULL) return;
  659. fprintf(stream, "(UA_LocalizedText){");
  660. UA_String_print(&p->locale, stream);
  661. fprintf(stream, ",");
  662. UA_String_print(&p->text, stream);
  663. fprintf(stream, "}");
  664. }
  665. #endif
  666. /* ExtensionObject */
  667. UA_TYPE_DELETE_DEFAULT(UA_ExtensionObject)
  668. UA_Int32 UA_ExtensionObject_deleteMembers(UA_ExtensionObject *p) {
  669. UA_Int32 retval = UA_SUCCESS;
  670. if(p == UA_NULL) return retval;
  671. retval |= UA_NodeId_deleteMembers(&p->typeId);
  672. retval |= UA_ByteString_deleteMembers(&p->body);
  673. return retval;
  674. }
  675. UA_Int32 UA_ExtensionObject_init(UA_ExtensionObject *p) {
  676. if(p == UA_NULL) return UA_ERROR;
  677. UA_ByteString_init(&p->body);
  678. p->encoding = 0;
  679. UA_NodeId_init(&p->typeId);
  680. return UA_SUCCESS;
  681. }
  682. UA_TYPE_NEW_DEFAULT(UA_ExtensionObject)
  683. UA_Int32 UA_ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst) {
  684. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  685. UA_Int32 retval = UA_SUCCESS;
  686. retval |= UA_Byte_copy(&src->encoding, &dst->encoding);
  687. retval |= UA_ByteString_copy(&src->body, &dst->body);
  688. retval |= UA_NodeId_copy(&src->typeId, &dst->typeId);
  689. return retval;
  690. }
  691. #ifdef DEBUG
  692. void UA_ExtensionObject_print(const UA_ExtensionObject *p, FILE *stream) {
  693. if(p == UA_NULL || stream == UA_NULL) return;
  694. fprintf(stream, "(UA_ExtensionObject){");
  695. UA_NodeId_print(&p->typeId, stream);
  696. if(p->encoding == UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING){
  697. fprintf(stream, ",UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING,");
  698. } else if(p->encoding == UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML) {
  699. fprintf(stream, ",UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISXML,");
  700. } else {
  701. fprintf(stream, ",UA_EXTENSIONOBJECT_ENCODINGMASK_NOBODYISENCODED,");
  702. }
  703. UA_ByteString_print(&p->body, stream);
  704. fprintf(stream, "}");
  705. }
  706. #endif
  707. /* DataValue */
  708. UA_TYPE_DELETE_DEFAULT(UA_DataValue)
  709. UA_Int32 UA_DataValue_deleteMembers(UA_DataValue *p) {
  710. UA_Int32 retval = UA_SUCCESS;
  711. if(p == UA_NULL) return retval;
  712. UA_Variant_deleteMembers(&p->value);
  713. return retval;
  714. }
  715. UA_Int32 UA_DataValue_init(UA_DataValue *p) {
  716. if(p == UA_NULL) return UA_ERROR;
  717. p->encodingMask = 0;
  718. p->serverPicoseconds = 0;
  719. UA_DateTime_init(&p->serverTimestamp);
  720. p->sourcePicoseconds = 0;
  721. UA_DateTime_init(&p->sourceTimestamp);
  722. UA_StatusCode_init(&p->status);
  723. UA_Variant_init(&p->value);
  724. return UA_SUCCESS;
  725. }
  726. UA_TYPE_NEW_DEFAULT(UA_DataValue)
  727. UA_Int32 UA_DataValue_copy(UA_DataValue const *src, UA_DataValue *dst) {
  728. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  729. UA_Int32 retval = UA_SUCCESS;
  730. UA_Byte_copy(&src->encodingMask, &dst->encodingMask);
  731. UA_Int16_copy(&src->serverPicoseconds, &dst->serverPicoseconds);
  732. UA_DateTime_copy(&src->serverTimestamp, &dst->serverTimestamp);
  733. UA_Int16_copy(&src->sourcePicoseconds, &dst->sourcePicoseconds);
  734. UA_DateTime_copy(&src->sourceTimestamp, &dst->sourceTimestamp);
  735. UA_StatusCode_copy(&src->status, &dst->status);
  736. UA_Variant_copy(&src->value, &dst->value);
  737. return retval;
  738. }
  739. #ifdef DEBUG
  740. void UA_DataValue_print(const UA_DataValue *p, FILE *stream) {
  741. if(p == UA_NULL || stream == UA_NULL) return;
  742. fprintf(stream, "(UA_DataValue){");
  743. UA_Byte_print(&p->encodingMask, stream);
  744. fprintf(stream, ",");
  745. UA_Variant_print(&p->value, stream);
  746. fprintf(stream, ",");
  747. UA_StatusCode_print(&p->status, stream);
  748. fprintf(stream, ",");
  749. UA_DateTime_print(&p->sourceTimestamp, stream);
  750. fprintf(stream, ",");
  751. UA_Int16_print(&p->sourcePicoseconds, stream);
  752. fprintf(stream, ",");
  753. UA_DateTime_print(&p->serverTimestamp, stream);
  754. fprintf(stream, ",");
  755. UA_Int16_print(&p->serverPicoseconds, stream);
  756. fprintf(stream, "}");
  757. }
  758. #endif
  759. /* Variant */
  760. UA_TYPE_DELETE_DEFAULT(UA_Variant)
  761. UA_Int32 UA_Variant_deleteMembers(UA_Variant *p) {
  762. UA_Int32 retval = UA_SUCCESS;
  763. if(p == UA_NULL) return retval;
  764. UA_Boolean hasDimensions = p->arrayDimensions != UA_NULL;
  765. if(p->data != UA_NULL) {
  766. retval |= UA_Array_delete(p->data, p->arrayLength, p->vt);
  767. p->data = UA_NULL;
  768. }
  769. if(hasDimensions) {
  770. UA_free(p->arrayDimensions);
  771. p->arrayDimensions = UA_NULL;
  772. }
  773. return retval;
  774. }
  775. UA_Int32 UA_Variant_init(UA_Variant *p) {
  776. if(p == UA_NULL) return UA_ERROR;
  777. p->arrayLength = -1; // no element, p->data == UA_NULL
  778. p->data = UA_NULL;
  779. p->arrayDimensions = UA_NULL;
  780. p->arrayDimensionsLength = -1;
  781. p->vt = &UA_.types[UA_INVALIDTYPE];
  782. return UA_SUCCESS;
  783. }
  784. UA_TYPE_NEW_DEFAULT(UA_Variant)
  785. UA_Int32 UA_Variant_copy(UA_Variant const *src, UA_Variant *dst) {
  786. if(src == UA_NULL || dst == UA_NULL)
  787. return UA_ERROR;
  788. UA_Int32 retval = UA_SUCCESS;
  789. dst->vt = src->vt;
  790. retval |= UA_Int32_copy(&src->arrayLength, &dst->arrayLength);
  791. retval |= UA_Int32_copy(&src->arrayDimensionsLength, &dst->arrayDimensionsLength);
  792. retval |= UA_Array_copy(src->data, src->arrayLength, src->vt, &dst->data);
  793. UA_Boolean hasDimensions = src->arrayDimensions != UA_NULL;
  794. if(hasDimensions)
  795. retval |= UA_Array_copy(src->arrayDimensions, src->arrayDimensionsLength,
  796. &UA_.types[UA_INT32], (void **)&dst->arrayDimensions);
  797. return retval;
  798. }
  799. #ifdef DEBUG
  800. void UA_Variant_print(const UA_Variant *p, FILE *stream) {
  801. if(p == UA_NULL || stream == UA_NULL) return;
  802. UA_UInt32 ns0id = UA_ns0ToVTableIndex(&p->vt->typeId);
  803. fprintf(stream, "(UA_Variant){/*%s*/", p->vt->name);
  804. if(p->vt == &UA_.types[ns0id])
  805. fprintf(stream, "UA_.types[%d]", ns0id);
  806. else if(p->vt == &UA_borrowed_.types[ns0id])
  807. fprintf(stream, "UA_borrowed_.types[%d]", ns0id);
  808. else
  809. fprintf(stream, "ERROR (not a builtin type)");
  810. UA_Int32_print(&p->arrayLength, stream);
  811. fprintf(stream, ",");
  812. UA_Array_print(p->data, p->arrayLength, p->vt, stream);
  813. fprintf(stream, ",");
  814. UA_Int32_print(&p->arrayDimensionsLength, stream);
  815. fprintf(stream, ",");
  816. UA_Array_print(p->arrayDimensions, p->arrayDimensionsLength, &UA_.types[UA_INT32], stream);
  817. fprintf(stream, "}");
  818. }
  819. #endif
  820. UA_Int32 UA_Variant_copySetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value) {
  821. if(v == UA_NULL || vt == UA_NULL || value == UA_NULL)
  822. return UA_ERROR;
  823. UA_Variant_init(v);
  824. v->vt = vt;
  825. v->arrayLength = 1; // no array but a single entry
  826. UA_Int32 retval = UA_SUCCESS;
  827. retval |= vt->new(&v->data);
  828. if(retval == UA_SUCCESS)
  829. retval |= vt->copy(value, v->data);
  830. return retval;
  831. }
  832. UA_Int32 UA_Variant_copySetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array) {
  833. if(v == UA_NULL || vt == UA_NULL || array == UA_NULL)
  834. return UA_ERROR;
  835. UA_Variant_init(v);
  836. v->vt = vt;
  837. v->arrayLength = arrayLength;
  838. return UA_Array_copy(array, arrayLength, vt, &v->data);
  839. }
  840. UA_Int32 UA_Variant_borrowSetValue(UA_Variant *v, UA_VTable_Entry *vt, const void *value) {
  841. if(v == UA_NULL || vt == UA_NULL || value == UA_NULL)
  842. return UA_ERROR;
  843. UA_Variant_init(v);
  844. v->vt = &UA_borrowed_.types[UA_ns0ToVTableIndex(&vt->typeId)];
  845. v->arrayLength = 1; // no array but a single entry
  846. v->data = (void *)value;
  847. return UA_SUCCESS;
  848. }
  849. UA_Int32 UA_Variant_borrowSetArray(UA_Variant *v, UA_VTable_Entry *vt, UA_Int32 arrayLength, const void *array) {
  850. if(v == UA_NULL || vt == UA_NULL || array == UA_NULL)
  851. return UA_ERROR;
  852. UA_Variant_init(v);
  853. v->vt = &UA_borrowed_.types[UA_ns0ToVTableIndex(&vt->typeId)];
  854. v->arrayLength = arrayLength;
  855. v->data = (void *)array;
  856. return UA_SUCCESS;
  857. }
  858. /* DiagnosticInfo */
  859. UA_TYPE_DELETE_DEFAULT(UA_DiagnosticInfo)
  860. UA_Int32 UA_DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p) {
  861. UA_Int32 retval = UA_SUCCESS;
  862. if(p == UA_NULL) return retval;
  863. if((p->encodingMask & UA_DIAGNOSTICINFO_ENCODINGMASK_INNERDIAGNOSTICINFO) && p->innerDiagnosticInfo != UA_NULL) {
  864. retval |= UA_DiagnosticInfo_delete(p->innerDiagnosticInfo);
  865. retval |= UA_String_deleteMembers(&p->additionalInfo);
  866. p->innerDiagnosticInfo = UA_NULL;
  867. }
  868. return retval;
  869. }
  870. UA_Int32 UA_DiagnosticInfo_init(UA_DiagnosticInfo *p) {
  871. if(p == UA_NULL) return UA_ERROR;
  872. UA_String_init(&p->additionalInfo);
  873. p->encodingMask = 0;
  874. p->innerDiagnosticInfo = UA_NULL;
  875. UA_StatusCode_init(&p->innerStatusCode);
  876. p->locale = 0;
  877. p->localizedText = 0;
  878. p->namespaceUri = 0;
  879. p->symbolicId = 0;
  880. return UA_SUCCESS;
  881. }
  882. UA_TYPE_NEW_DEFAULT(UA_DiagnosticInfo)
  883. UA_Int32 UA_DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst) {
  884. if(src == UA_NULL || dst == UA_NULL) return UA_ERROR;
  885. UA_Int32 retval = UA_SUCCESS;
  886. retval |= UA_String_copy(&src->additionalInfo, &dst->additionalInfo);
  887. retval |= UA_Byte_copy(&src->encodingMask, &dst->encodingMask);
  888. retval |= UA_StatusCode_copy(&src->innerStatusCode, &dst->innerStatusCode);
  889. if(src->innerDiagnosticInfo) {
  890. retval |= UA_alloc((void **)&dst->innerDiagnosticInfo, sizeof(UA_DiagnosticInfo));
  891. if(retval == UA_SUCCESS)
  892. retval |= UA_DiagnosticInfo_copy(src->innerDiagnosticInfo, dst->innerDiagnosticInfo);
  893. } else
  894. dst->innerDiagnosticInfo = UA_NULL;
  895. retval |= UA_Int32_copy(&src->locale, &dst->locale);
  896. retval |= UA_Int32_copy(&src->localizedText, &dst->localizedText);
  897. retval |= UA_Int32_copy(&src->namespaceUri, &dst->namespaceUri);
  898. retval |= UA_Int32_copy(&src->symbolicId, &dst->symbolicId);
  899. return retval;
  900. }
  901. #ifdef DEBUG
  902. void UA_DiagnosticInfo_print(const UA_DiagnosticInfo *p, FILE *stream) {
  903. if(p == UA_NULL || stream == UA_NULL) return;
  904. fprintf(stream, "(UA_DiagnosticInfo){");
  905. UA_Byte_print(&p->encodingMask, stream);
  906. fprintf(stream, ",");
  907. UA_Int32_print(&p->symbolicId, stream);
  908. fprintf(stream, ",");
  909. UA_Int32_print(&p->namespaceUri, stream);
  910. fprintf(stream, ",");
  911. UA_Int32_print(&p->localizedText, stream);
  912. fprintf(stream, ",");
  913. UA_Int32_print(&p->locale, stream);
  914. fprintf(stream, ",");
  915. UA_String_print(&p->additionalInfo, stream);
  916. fprintf(stream, ",");
  917. UA_StatusCode_print(&p->innerStatusCode, stream);
  918. fprintf(stream, ",");
  919. if(p->innerDiagnosticInfo != UA_NULL) {
  920. fprintf(stream, "&");
  921. UA_DiagnosticInfo_print(p->innerDiagnosticInfo, stream);
  922. } else {
  923. fprintf(stream, "UA_NULL");
  924. }
  925. fprintf(stream, "}");
  926. }
  927. #endif
  928. /* InvalidType */
  929. UA_Int32 UA_InvalidType_free(UA_InvalidType *p) {
  930. return UA_ERR_INVALID_VALUE;
  931. }
  932. UA_Int32 UA_InvalidType_delete(UA_InvalidType *p) {
  933. return UA_ERR_INVALID_VALUE;
  934. }
  935. UA_Int32 UA_InvalidType_deleteMembers(UA_InvalidType *p) {
  936. return UA_ERR_INVALID_VALUE;
  937. }
  938. UA_Int32 UA_InvalidType_init(UA_InvalidType *p) {
  939. return UA_ERR_INVALID_VALUE;
  940. }
  941. UA_Int32 UA_InvalidType_copy(UA_InvalidType const *src, UA_InvalidType *dst) {
  942. return UA_ERR_INVALID_VALUE;
  943. }
  944. UA_Int32 UA_InvalidType_new(UA_InvalidType **p) {
  945. return UA_ERR_INVALID_VALUE;
  946. }
  947. #ifdef DEBUG
  948. void UA_InvalidType_print(const UA_InvalidType *p, FILE *stream) {
  949. if(p == UA_NULL || stream == UA_NULL) return;
  950. fprintf(stream, "(UA_InvalidType){ERROR (invalid type)}");
  951. }
  952. #endif
  953. /*********/
  954. /* Array */
  955. /*********/
  956. UA_Int32 UA_Array_new(void **p, UA_Int32 noElements, UA_VTable_Entry *vt) {
  957. if(vt == UA_NULL)
  958. return UA_ERROR;
  959. if(noElements <= 0) {
  960. *p = UA_NULL;
  961. return UA_SUCCESS;
  962. }
  963. // FIXME! Arrays cannot be larger than 2**20.
  964. // This was randomly chosen so that the development VM does not blow up.
  965. if(noElements > 1048576) {
  966. *p = UA_NULL;
  967. return UA_ERROR;
  968. }
  969. UA_Int32 retval = UA_SUCCESS;
  970. retval = UA_alloc(p, vt->memSize * noElements);
  971. if(retval != UA_SUCCESS)
  972. return retval;
  973. retval = UA_Array_init(*p, noElements, vt);
  974. if(retval != UA_SUCCESS) {
  975. UA_free(*p);
  976. *p = UA_NULL;
  977. }
  978. return retval;
  979. }
  980. UA_Int32 UA_Array_init(void *p, UA_Int32 noElements, UA_VTable_Entry *vt) {
  981. if(p == UA_NULL || vt == UA_NULL)
  982. return UA_ERROR;
  983. UA_Int32 retval = UA_SUCCESS;
  984. char *cp = (char *)p; // so compilers allow pointer arithmetic
  985. UA_UInt32 memSize = vt->memSize;
  986. for(UA_Int32 i = 0;i < noElements && retval == UA_SUCCESS;i++) {
  987. retval |= vt->init(cp);
  988. cp += memSize;
  989. }
  990. return retval;
  991. }
  992. UA_Int32 UA_Array_delete(void *p, UA_Int32 noElements, UA_VTable_Entry *vt) {
  993. if(p == UA_NULL)
  994. return UA_SUCCESS;
  995. if(vt == UA_NULL)
  996. return UA_ERROR;
  997. char *cp = (char *)p; // so compilers allow pointer arithmetic
  998. UA_UInt32 memSize = vt->memSize;
  999. UA_Int32 retval = UA_SUCCESS;
  1000. for(UA_Int32 i = 0;i < noElements;i++) {
  1001. retval |= vt->deleteMembers(cp);
  1002. cp += memSize;
  1003. }
  1004. UA_free(p);
  1005. return retval;
  1006. }
  1007. UA_Int32 UA_Array_copy(const void *src, UA_Int32 noElements, UA_VTable_Entry *vt, void **dst) {
  1008. if(src == UA_NULL || dst == UA_NULL || vt == UA_NULL)
  1009. return UA_ERROR;
  1010. UA_Int32 retval = UA_Array_new(dst, noElements, vt);
  1011. if(retval != UA_SUCCESS){
  1012. *dst = UA_NULL;
  1013. return retval;
  1014. }
  1015. char *csrc = (char *)src; // so compilers allow pointer arithmetic
  1016. char *cdst = (char *)*dst;
  1017. UA_UInt32 memSize = vt->memSize;
  1018. UA_Int32 i = 0;
  1019. for(;i < noElements && retval == UA_SUCCESS;i++) {
  1020. retval |= vt->copy(csrc, cdst);
  1021. csrc += memSize;
  1022. cdst += memSize;
  1023. }
  1024. if(retval != UA_SUCCESS) {
  1025. i--; // undo last increase
  1026. UA_Array_delete(*dst, i, vt);
  1027. *dst = UA_NULL;
  1028. }
  1029. return retval;
  1030. }
  1031. #ifdef DEBUG
  1032. void UA_Array_print(const void *p, UA_Int32 noElements, UA_VTable_Entry *vt, FILE *stream) {
  1033. if(p == UA_NULL || vt == UA_NULL || stream == UA_NULL) return;
  1034. fprintf(stream, "(%s){", vt->name);
  1035. char *cp = (char *)p; // so compilers allow pointer arithmetic
  1036. UA_UInt32 memSize = vt->memSize;
  1037. for(UA_Int32 i=0;i < noElements;i++) {
  1038. vt->print(cp, stream);
  1039. fprintf(stream, ",");
  1040. cp += memSize;
  1041. }
  1042. }
  1043. #endif