opcua_basictypes.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350
  1. #include <stdio.h> // printf
  2. #include <stdlib.h> // alloc, free
  3. #include <string.h>
  4. #include "opcua.h"
  5. #include "opcua_basictypes.h"
  6. UA_Int32 UA_encode(void* const data, UA_Int32 *pos, UA_Int32 type, UA_Byte* dst) {
  7. return UA_[type].encode(data,pos,dst);
  8. }
  9. UA_Int32 UA_decode(UA_Byte* const data, UA_Int32* pos, UA_Int32 type, void* dst){
  10. return UA_[type].decode(data,pos,dst);
  11. }
  12. UA_Int32 UA_calcSize(void* const data, UA_UInt32 type) {
  13. return (UA_[type].calcSize)(data);
  14. }
  15. UA_Int32 UA_Array_calcSize(UA_Int32 nElements, UA_Int32 type, void const ** const data) {
  16. int length = sizeof(UA_Int32);
  17. int i;
  18. if (nElements > 0) {
  19. for(i=0; i<nElements;i++) {
  20. length += UA_calcSize((void*)data[i],type);
  21. }
  22. }
  23. return length;
  24. }
  25. UA_Int32 UA_Array_encode(void const **src, UA_Int32 noElements, UA_Int32 type, UA_Int32* pos, UA_Byte * dst) {
  26. UA_Int32 retVal = UA_SUCCESS;
  27. UA_Int32 i = 0;
  28. UA_Int32_encode(&noElements, pos, dst);
  29. for(i=0; i<noElements; i++) {
  30. retVal |= UA_[type].encode((void*)src[i], pos, dst);
  31. }
  32. return retVal;
  33. }
  34. UA_Int32 UA_Array_decode(UA_Byte const * src, UA_Int32 noElements, UA_Int32 type, UA_Int32* pos, void ** const dst) {
  35. UA_Int32 retval = UA_SUCCESS;
  36. UA_Int32 i = 0;
  37. for(i=0; i<noElements; i++) {
  38. retval |= UA_[type].decode(src, pos, (void*)dst[i]);
  39. }
  40. return retval;
  41. }
  42. UA_Int32 UA_Array_deleteMembers(void ** p,UA_Int32 noElements, UA_Int32 type) {
  43. UA_Int32 retval = UA_SUCCESS;
  44. UA_Int32 i = 0;
  45. for(i=0; i<noElements; i++) {
  46. retval |= UA_[type].delete((void*)p[i]);
  47. }
  48. return retval;
  49. }
  50. UA_Int32 UA_Array_delete(void **p,UA_Int32 noElements, UA_Int32 type) {
  51. UA_Int32 retval = UA_SUCCESS;
  52. retval |= UA_Array_deleteMembers(p,noElements,type);
  53. retval |= UA_free(p);
  54. return retval;
  55. }
  56. // TODO: Do we need to implement? We would need to add init to the VTable...
  57. // UA_Int32 UA_Array_init(void **p,UA_Int32 noElements, UA_Int32 type) {
  58. /** p is the address of a pointer to an array of pointers (type**).
  59. * [p] -> [p1, p2, p3, p4]
  60. * +-> struct 1, ...
  61. */
  62. UA_Int32 UA_Array_new(void **p,UA_Int32 noElements, UA_Int32 type) {
  63. UA_Int32 retval = UA_SUCCESS;
  64. UA_Int32 i;
  65. // Get memory for the pointers
  66. retval |= UA_alloc(p, sizeof(void*)*noElements);
  67. // Then allocate all the elements. We could allocate all the members in one chunk and
  68. // calculate the addresses to prevent memory segmentation. This would however not call
  69. // init for each member
  70. void *arr = *p;
  71. for(i=0; i<noElements; i++) {
  72. retval |= UA_[type].new((void**)arr+i);
  73. }
  74. return retval;
  75. }
  76. UA_Int32 _UA_free(void * ptr,char* f,int l){
  77. DBG_VERBOSE(printf("UA_free;%p;;%s;%d\n",ptr,f,l); fflush(stdout));
  78. if (UA_NULL != ptr) {
  79. free(ptr);
  80. }
  81. return UA_SUCCESS;
  82. }
  83. void const * UA_alloc_lastptr;
  84. UA_Int32 _UA_alloc(void ** ptr, int size,char* f,int l){
  85. if(ptr == UA_NULL) return UA_ERR_INVALID_VALUE;
  86. UA_alloc_lastptr = *ptr = malloc(size);
  87. DBG_VERBOSE(printf("UA_alloc;%p;%d;%s;%d\n",*ptr,size,f,l); fflush(stdout));
  88. if(*ptr == UA_NULL) return UA_ERR_NO_MEMORY;
  89. return UA_SUCCESS;
  90. }
  91. UA_Int32 UA_memcpy(void * dst, void const * src, int size){
  92. if(dst == UA_NULL) return UA_ERR_INVALID_VALUE;
  93. DBG_VERBOSE(printf("UA_memcpy;%p;%p;%d\n",dst,src,size));
  94. memcpy(dst, src, size);
  95. return UA_SUCCESS;
  96. }
  97. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Boolean)
  98. UA_Int32 UA_Boolean_encode(UA_Boolean const * src, UA_Int32* pos, UA_Byte * dst) {
  99. UA_Boolean tmpBool = ((*src > 0) ? UA_TRUE : UA_FALSE);
  100. memcpy(&(dst[(*pos)++]), &tmpBool, sizeof(UA_Boolean));
  101. return UA_SUCCESS;
  102. }
  103. UA_Int32 UA_Boolean_decode(UA_Byte const * src, UA_Int32* pos, UA_Boolean * dst) {
  104. *dst = ((UA_Boolean) (src[(*pos)++]) > 0) ? UA_TRUE : UA_FALSE;
  105. return UA_SUCCESS;
  106. }
  107. UA_Int32 UA_Boolean_init(UA_Boolean * p){
  108. if(p==UA_NULL)return UA_ERROR;
  109. *p = UA_FALSE;
  110. return UA_SUCCESS;
  111. }
  112. UA_TYPE_METHOD_DELETE_FREE(UA_Boolean)
  113. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Boolean)
  114. UA_TYPE_METHOD_NEW_DEFAULT(UA_Boolean)
  115. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Byte)
  116. UA_Int32 UA_Byte_encode(UA_Byte const * src, UA_Int32* pos, UA_Byte * dst) {
  117. dst[(*pos)++] = *src;
  118. return UA_SUCCESS;
  119. }
  120. UA_Int32 UA_Byte_decode(UA_Byte const * src, UA_Int32* pos, UA_Byte * dst) {
  121. *dst = src[(*pos)++];
  122. return UA_SUCCESS;
  123. }
  124. UA_TYPE_METHOD_DELETE_FREE(UA_Byte)
  125. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Byte)
  126. UA_TYPE_METHOD_INIT_DEFAULT(UA_Byte)
  127. UA_TYPE_METHOD_NEW_DEFAULT(UA_Byte)
  128. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_SByte)
  129. UA_Int32 UA_SByte_encode(UA_SByte const * src, UA_Int32* pos, UA_Byte * dst) {
  130. dst[(*pos)++] = *src;
  131. return UA_SUCCESS;
  132. }
  133. UA_Int32 UA_SByte_decode(UA_Byte const * src, UA_Int32* pos, UA_SByte * dst) {
  134. *dst = src[(*pos)++];
  135. return 1;
  136. }
  137. UA_TYPE_METHOD_DELETE_FREE(UA_SByte)
  138. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_SByte)
  139. UA_TYPE_METHOD_INIT_DEFAULT(UA_SByte)
  140. UA_TYPE_METHOD_NEW_DEFAULT(UA_SByte)
  141. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_UInt16)
  142. UA_Int32 UA_UInt16_encode(UA_UInt16 const *src, UA_Int32* pos, UA_Byte * dst) {
  143. dst[(*pos)++] = (*src & 0x00FF) >> 0;
  144. dst[(*pos)++] = (*src & 0xFF00) >> 8;
  145. return UA_SUCCESS;
  146. }
  147. UA_Int32 UA_UInt16_decode(UA_Byte const * src, UA_Int32* pos, UA_UInt16* dst) {
  148. *dst = (UA_UInt16) src[(*pos)++] << 0;
  149. *dst |= (UA_UInt16) src[(*pos)++] << 8;
  150. return UA_SUCCESS;
  151. }
  152. UA_TYPE_METHOD_DELETE_FREE(UA_UInt16)
  153. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_UInt16)
  154. UA_TYPE_METHOD_INIT_DEFAULT(UA_UInt16)
  155. UA_TYPE_METHOD_NEW_DEFAULT(UA_UInt16)
  156. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Int16)
  157. UA_Int32 UA_Int16_encode(UA_Int16 const * src, UA_Int32* pos, UA_Byte* dst) {
  158. return UA_UInt16_encode((UA_UInt16 const *) src,pos,dst);
  159. }
  160. UA_Int32 UA_Int16_decode(UA_Byte const * src, UA_Int32* pos, UA_Int16 *dst) {
  161. *dst = (UA_Int16) (((UA_SByte) (src[(*pos)++]) & 0xFF) << 0);
  162. *dst |= (UA_Int16) (((UA_SByte) (src[(*pos)++]) & 0xFF) << 8);
  163. return UA_SUCCESS;
  164. }
  165. UA_TYPE_METHOD_DELETE_FREE(UA_Int16)
  166. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Int16)
  167. UA_TYPE_METHOD_INIT_DEFAULT(UA_Int16)
  168. UA_TYPE_METHOD_NEW_DEFAULT(UA_Int16)
  169. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Int32)
  170. UA_Int32 UA_Int32_encode(UA_Int32 const * src, UA_Int32* pos, UA_Byte* dst) {
  171. dst[(*pos)++] = (*src & 0x000000FF) >> 0;
  172. dst[(*pos)++] = (*src & 0x0000FF00) >> 8;
  173. dst[(*pos)++] = (*src & 0x00FF0000) >> 16;
  174. dst[(*pos)++] = (*src & 0xFF000000) >> 24;
  175. return UA_SUCCESS;
  176. }
  177. UA_Int32 UA_Int32_decode(UA_Byte const * src, UA_Int32* pos, UA_Int32* dst) {
  178. *dst = (UA_Int32) (((UA_SByte) (src[(*pos)++]) & 0xFF) << 0);
  179. *dst |= (UA_Int32) (((UA_SByte) (src[(*pos)++]) & 0xFF) << 8);
  180. *dst |= (UA_Int32) (((UA_SByte) (src[(*pos)++]) & 0xFF) << 16);
  181. *dst |= (UA_Int32) (((UA_SByte) (src[(*pos)++]) & 0xFF) << 24);
  182. return UA_SUCCESS;
  183. }
  184. UA_TYPE_METHOD_DELETE_FREE(UA_Int32)
  185. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Int32)
  186. UA_TYPE_METHOD_INIT_DEFAULT(UA_Int32)
  187. UA_TYPE_METHOD_NEW_DEFAULT(UA_Int32)
  188. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_UInt32)
  189. UA_Int32 UA_UInt32_encode(UA_UInt32 const * src, UA_Int32* pos, UA_Byte* dst) {
  190. return UA_Int32_encode((UA_Int32 const *)src,pos,dst);
  191. }
  192. UA_Int32 UA_UInt32_decode(UA_Byte const * src, UA_Int32* pos, UA_UInt32 *dst) {
  193. UA_UInt32 t1 = (UA_UInt32)((UA_Byte)(src[(*pos)++] & 0xFF));
  194. UA_UInt32 t2 = (UA_UInt32)((UA_Byte)(src[(*pos)++]& 0xFF) << 8);
  195. UA_UInt32 t3 = (UA_UInt32)((UA_Byte)(src[(*pos)++]& 0xFF) << 16);
  196. UA_UInt32 t4 = (UA_UInt32)((UA_Byte)(src[(*pos)++]& 0xFF) << 24);
  197. *dst = t1 + t2 + t3 + t4;
  198. return UA_SUCCESS;
  199. }
  200. UA_TYPE_METHOD_DELETE_FREE(UA_UInt32)
  201. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_UInt32)
  202. UA_TYPE_METHOD_INIT_DEFAULT(UA_UInt32)
  203. UA_TYPE_METHOD_NEW_DEFAULT(UA_UInt32)
  204. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Int64)
  205. UA_Int32 UA_Int64_encode(UA_Int64 const * src, UA_Int32* pos, UA_Byte *dst) {
  206. dst[(*pos)++] = (*src & 0x00000000000000FF) >> 0;
  207. dst[(*pos)++] = (*src & 0x000000000000FF00) >> 8;
  208. dst[(*pos)++] = (*src & 0x0000000000FF0000) >> 16;
  209. dst[(*pos)++] = (*src & 0x00000000FF000000) >> 24;
  210. dst[(*pos)++] = (*src & 0x000000FF00000000) >> 32;
  211. dst[(*pos)++] = (*src & 0x0000FF0000000000) >> 40;
  212. dst[(*pos)++] = (*src & 0x00FF000000000000) >> 48;
  213. dst[(*pos)++] = (*src & 0xFF00000000000000) >> 56;
  214. return UA_SUCCESS;
  215. }
  216. UA_Int32 UA_Int64_decode(UA_Byte const * src, UA_Int32* pos, UA_Int64* dst) {
  217. *dst = (UA_Int64) src[(*pos)++] << 0;
  218. *dst |= (UA_Int64) src[(*pos)++] << 8;
  219. *dst |= (UA_Int64) src[(*pos)++] << 16;
  220. *dst |= (UA_Int64) src[(*pos)++] << 24;
  221. *dst |= (UA_Int64) src[(*pos)++] << 32;
  222. *dst |= (UA_Int64) src[(*pos)++] << 40;
  223. *dst |= (UA_Int64) src[(*pos)++] << 48;
  224. *dst |= (UA_Int64) src[(*pos)++] << 56;
  225. return UA_SUCCESS;
  226. }
  227. UA_TYPE_METHOD_DELETE_FREE(UA_Int64)
  228. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Int64)
  229. UA_TYPE_METHOD_INIT_DEFAULT(UA_Int64)
  230. UA_TYPE_METHOD_NEW_DEFAULT(UA_Int64)
  231. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_UInt64)
  232. UA_Int32 UA_UInt64_encode(UA_UInt64 const * src , UA_Int32* pos, UA_Byte * dst) {
  233. return UA_Int64_encode((UA_Int64 const *)src,pos,dst);
  234. }
  235. UA_Int32 UA_UInt64_decode(UA_Byte const * src, UA_Int32* pos, UA_UInt64* dst) {
  236. UA_UInt64 t1 = (UA_UInt64) src[(*pos)++];
  237. UA_UInt64 t2 = (UA_UInt64) src[(*pos)++] << 8;
  238. UA_UInt64 t3 = (UA_UInt64) src[(*pos)++] << 16;
  239. UA_UInt64 t4 = (UA_UInt64) src[(*pos)++] << 24;
  240. UA_UInt64 t5 = (UA_UInt64) src[(*pos)++] << 32;
  241. UA_UInt64 t6 = (UA_UInt64) src[(*pos)++] << 40;
  242. UA_UInt64 t7 = (UA_UInt64) src[(*pos)++] << 48;
  243. UA_UInt64 t8 = (UA_UInt64) src[(*pos)++] << 56;
  244. *dst = t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
  245. return UA_SUCCESS;
  246. }
  247. UA_TYPE_METHOD_DELETE_FREE(UA_UInt64)
  248. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_UInt64)
  249. UA_TYPE_METHOD_INIT_DEFAULT(UA_UInt64)
  250. UA_TYPE_METHOD_NEW_DEFAULT(UA_UInt64)
  251. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Float)
  252. // FIXME: Implement
  253. UA_Int32 UA_Float_decode(UA_Byte const * src, UA_Int32* pos, UA_Float* dst) {
  254. memcpy(dst, &(src[*pos]), sizeof(UA_Float));
  255. *pos += sizeof(UA_Float);
  256. return UA_SUCCESS;
  257. }
  258. // FIXME: Implement
  259. UA_Int32 UA_Float_encode(UA_Float const * src, UA_Int32* pos, UA_Byte* dst) {
  260. memcpy(&(dst[*pos]), src, sizeof(UA_Float));
  261. *pos += sizeof(UA_Float);
  262. return UA_SUCCESS;
  263. }
  264. UA_TYPE_METHOD_DELETE_FREE(UA_Float)
  265. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Float)
  266. UA_Int32 UA_Float_init(UA_Float * p){
  267. if(p==UA_NULL)return UA_ERROR;
  268. *p = (UA_Float)0.0;
  269. return UA_SUCCESS;
  270. }
  271. UA_TYPE_METHOD_NEW_DEFAULT(UA_Float)
  272. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_Double)
  273. // FIXME: Implement
  274. UA_Int32 UA_Double_decode(UA_Byte const * src, UA_Int32* pos, UA_Double * dst) {
  275. UA_Double tmpDouble;
  276. tmpDouble = (UA_Double) (src[*pos]);
  277. *pos += sizeof(UA_Double);
  278. *dst = tmpDouble;
  279. return UA_SUCCESS;
  280. }
  281. // FIXME: Implement
  282. UA_Int32 UA_Double_encode(UA_Double const * src, UA_Int32 *pos, UA_Byte* dst) {
  283. memcpy(&(dst[*pos]), src, sizeof(UA_Double));
  284. *pos += sizeof(UA_Double);
  285. return UA_SUCCESS;
  286. }
  287. UA_TYPE_METHOD_DELETE_FREE(UA_Double)
  288. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_Double)
  289. UA_TYPE_METHOD_INIT_DEFAULT(UA_Double)
  290. UA_TYPE_METHOD_NEW_DEFAULT(UA_Double)
  291. UA_Int32 UA_String_calcSize(UA_String const * string) {
  292. if (string == UA_NULL) {
  293. // internal size for UA_memalloc
  294. return sizeof(UA_String);
  295. } else {
  296. // binary encoding size
  297. if (string->length > 0) {
  298. return sizeof(UA_Int32) + string->length * sizeof(UA_Byte);
  299. } else {
  300. return sizeof(UA_Int32);
  301. }
  302. }
  303. }
  304. UA_Int32 UA_String_encode(UA_String const * src, UA_Int32* pos, UA_Byte* dst) {
  305. UA_Int32_encode(&(src->length),pos,dst);
  306. if (src->length > 0) {
  307. UA_memcpy(&(dst[*pos]), src->data, src->length);
  308. *pos += src->length;
  309. }
  310. return UA_SUCCESS;
  311. }
  312. UA_Int32 UA_String_decode(UA_Byte const * src, UA_Int32* pos, UA_String * dst) {
  313. UA_Int32 retval = UA_SUCCESS;
  314. retval |= UA_Int32_decode(src,pos,&(dst->length));
  315. if (dst->length > 0) {
  316. retval |= UA_alloc((void**)&(dst->data),dst->length);
  317. retval |= UA_memcpy(dst->data,&(src[*pos]),dst->length);
  318. *pos += dst->length;
  319. } else {
  320. dst->data = UA_NULL;
  321. }
  322. return retval;
  323. }
  324. UA_TYPE_METHOD_DELETE_STRUCT(UA_String)
  325. UA_Int32 UA_String_deleteMembers(UA_String* p) { return UA_free(p->data); }
  326. UA_Int32 UA_String_copy(UA_String const * src, UA_String* dst) {
  327. UA_Int32 retval = UA_SUCCESS;
  328. dst->data = UA_NULL;
  329. dst->length = -1;
  330. if (src->length > 0) {
  331. retval |= UA_alloc((void**)&(dst->data), src->length);
  332. if (retval == UA_SUCCESS) {
  333. retval |= UA_memcpy((void*)dst->data, src->data, src->length);
  334. dst->length = src->length;
  335. }
  336. }
  337. return retval;
  338. }
  339. UA_Int32 UA_String_copycstring(char const * src, UA_String* dst) {
  340. UA_Int32 retval = UA_SUCCESS;
  341. dst->length = strlen(src);
  342. dst->data = UA_NULL;
  343. if (dst->length > 0) {
  344. retval |= UA_alloc((void**)&(dst->data), dst->length);
  345. if (retval == UA_SUCCESS) {
  346. retval |= UA_memcpy((void*)dst->data, src, dst->length);
  347. }
  348. }
  349. return retval;
  350. }
  351. UA_String UA_String_null = { -1, UA_NULL };
  352. UA_Int32 UA_String_init(UA_String* p){
  353. if(p==UA_NULL)return UA_ERROR;
  354. p->length = -1;
  355. p->data = UA_NULL;
  356. return UA_SUCCESS;
  357. }
  358. UA_TYPE_METHOD_NEW_DEFAULT(UA_String)
  359. UA_Int32 UA_String_compare(UA_String* string1, UA_String* string2) {
  360. UA_Int32 retval;
  361. if (string1->length == 0 && string2->length == 0) {
  362. retval = UA_EQUAL;
  363. } else if (string1->length == -1 && string2->length == -1) {
  364. retval = UA_EQUAL;
  365. } else if (string1->length != string2->length) {
  366. retval = UA_NOT_EQUAL;
  367. } else {
  368. // casts to overcome signed warnings
  369. // FIXME: map return of strncmp to UA_EQUAL/UA_NOT_EQUAL
  370. retval = strncmp((char const*)string1->data,(char const*)string2->data,string1->length);
  371. }
  372. return retval;
  373. }
  374. void UA_String_printf(char* label, UA_String* string) {
  375. printf("%s {Length=%d, Data=%.*s}\n", label, string->length,
  376. string->length, (char*)string->data);
  377. }
  378. void UA_String_printx(char* label, UA_String* string) {
  379. int i;
  380. if (string == UA_NULL) { printf("%s {NULL}\n", label); return; }
  381. printf("%s {Length=%d, Data=", label, string->length);
  382. if (string->length > 0) {
  383. for (i = 0; i < string->length; i++) {
  384. printf("%c%d", i == 0 ? '{' : ',', (string->data)[i]);
  385. // if (i > 0 && !(i%20)) { printf("\n\t"); }
  386. }
  387. } else {
  388. printf("{");
  389. }
  390. printf("}}\n");
  391. }
  392. void UA_String_printx_hex(char* label, UA_String* string) {
  393. int i;
  394. printf("%s {Length=%d, Data=", label, string->length);
  395. if (string->length > 0) {
  396. for (i = 0; i < string->length; i++) {
  397. printf("%c%x", i == 0 ? '{' : ',', (string->data)[i]);
  398. }
  399. } else {
  400. printf("{");
  401. }
  402. printf("}}\n");
  403. }
  404. // TODO: should we really handle UA_String and UA_ByteString the same way?
  405. UA_TYPE_METHOD_CALCSIZE_AS(UA_ByteString, UA_String)
  406. UA_TYPE_METHOD_ENCODE_AS(UA_ByteString, UA_String)
  407. UA_TYPE_METHOD_DECODE_AS(UA_ByteString, UA_String)
  408. UA_TYPE_METHOD_DELETE_AS(UA_ByteString, UA_String)
  409. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_ByteString, UA_String)
  410. UA_TYPE_METHOD_INIT_AS(UA_ByteString, UA_String)
  411. UA_TYPE_METHOD_NEW_DEFAULT(UA_ByteString)
  412. UA_Int32 UA_ByteString_compare(UA_ByteString *string1, UA_ByteString *string2) {
  413. return UA_String_compare((UA_String*) string1, (UA_String*) string2);
  414. }
  415. void UA_ByteString_printf(char* label, UA_ByteString* string) {
  416. UA_String_printf(label, (UA_String*) string);
  417. }
  418. void UA_ByteString_printx(char* label, UA_ByteString* string) {
  419. UA_String_printx(label, (UA_String*) string);
  420. }
  421. void UA_ByteString_printx_hex(char* label, UA_ByteString* string) {
  422. UA_String_printx_hex(label, (UA_String*) string);
  423. }
  424. UA_Byte UA_Byte_securityPoliceNoneData[] = "http://opcfoundation.org/UA/SecurityPolicy#None";
  425. // sizeof()-1 : discard the implicit null-terminator of the c-char-string
  426. UA_ByteString UA_ByteString_securityPoliceNone = { sizeof(UA_Byte_securityPoliceNoneData)-1, UA_Byte_securityPoliceNoneData };
  427. UA_Int32 UA_ByteString_copy(UA_ByteString const * src, UA_ByteString* dst) {
  428. return UA_String_copy((UA_String const*)src,(UA_String*)dst);
  429. }
  430. UA_Int32 UA_ByteString_newMembers(UA_ByteString* p, UA_Int32 length) {
  431. UA_Int32 retval = UA_SUCCESS;
  432. if ((retval |= UA_alloc((void**)&(p->data),length)) == UA_SUCCESS) {
  433. p->length = length;
  434. } else {
  435. p->length = length;
  436. p->data = UA_NULL;
  437. }
  438. return retval;
  439. }
  440. UA_Int32 UA_Guid_calcSize(UA_Guid const * p) {
  441. if (p == UA_NULL) {
  442. return sizeof(UA_Guid);
  443. } else {
  444. return 16;
  445. }
  446. }
  447. UA_Int32 UA_Guid_encode(UA_Guid const *src, UA_Int32* pos, UA_Byte* dst) {
  448. UA_Int32 retval = UA_SUCCESS;
  449. int i=0;
  450. retval |= UA_UInt32_encode(&(src->data1), pos, dst);
  451. retval |= UA_UInt16_encode(&(src->data2), pos, dst);
  452. retval |= UA_UInt16_encode(&(src->data3), pos, dst);
  453. for (i=0;i<8;i++) {
  454. retval |= UA_Byte_encode(&(src->data4[i]), pos, dst);
  455. }
  456. return UA_SUCCESS;
  457. }
  458. UA_Int32 UA_Guid_decode(UA_Byte const * src, UA_Int32* pos, UA_Guid *dst) {
  459. UA_Int32 retval = UA_SUCCESS;
  460. int i=0;
  461. retval |= UA_UInt32_decode(src,pos,&(dst->data1));
  462. retval |= UA_UInt16_decode(src,pos,&(dst->data2));
  463. retval |= UA_UInt16_decode(src,pos,&(dst->data3));
  464. for (i=0;i<8;i++) {
  465. retval |= UA_Byte_decode(src,pos,&(dst->data4[i]));
  466. }
  467. return retval;
  468. }
  469. UA_TYPE_METHOD_DELETE_STRUCT(UA_Guid)
  470. UA_Int32 UA_Guid_deleteMembers(UA_Guid* p) { return UA_SUCCESS; }
  471. UA_Int32 UA_Guid_compare(UA_Guid *g1, UA_Guid *g2) {
  472. return memcmp(g1, g2, sizeof(UA_Guid));
  473. }
  474. UA_Int32 UA_Guid_init(UA_Guid* p){
  475. if(p==UA_NULL)return UA_ERROR;
  476. p->data1 = 0;
  477. p->data2 = 0;
  478. p->data3 = 0;
  479. memset(p->data4,8,sizeof(UA_Byte));
  480. return UA_SUCCESS;
  481. }
  482. UA_TYPE_METHOD_NEW_DEFAULT(UA_Guid)
  483. UA_Int32 UA_LocalizedText_calcSize(UA_LocalizedText const * p) {
  484. UA_Int32 length = 0;
  485. if (p==UA_NULL) {
  486. // size for UA_memalloc
  487. length = sizeof(UA_LocalizedText);
  488. } else {
  489. // size for binary encoding
  490. length += 1; // p->encodingMask;
  491. if (p->encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE) {
  492. length += UA_String_calcSize(&(p->locale));
  493. }
  494. if (p->encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT) {
  495. length += UA_String_calcSize(&(p->text));
  496. }
  497. }
  498. return length;
  499. }
  500. UA_Int32 UA_LocalizedText_encode(UA_LocalizedText const * src, UA_Int32 *pos,
  501. UA_Byte* dst) {
  502. UA_Int32 retval = UA_SUCCESS;
  503. retval |= UA_Byte_encode(&(src->encodingMask),pos,dst);
  504. if (src->encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE) {
  505. UA_String_encode(&(src->locale),pos,dst);
  506. }
  507. if (src->encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT) {
  508. UA_String_encode(&(src->text),pos,dst);
  509. }
  510. return retval;
  511. }
  512. UA_Int32 UA_LocalizedText_decode(UA_Byte const * src, UA_Int32 *pos,
  513. UA_LocalizedText *dst) {
  514. UA_Int32 retval = UA_SUCCESS;
  515. retval |= UA_String_copy(&UA_String_null,&(dst->locale));
  516. retval |= UA_String_copy(&UA_String_null,&(dst->text));
  517. retval |= UA_Byte_decode(src,pos,&(dst->encodingMask));
  518. if (dst->encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE) {
  519. retval |= UA_String_decode(src,pos,&(dst->locale));
  520. }
  521. if (dst->encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT) {
  522. retval |= UA_String_decode(src,pos,&(dst->text));
  523. }
  524. return retval;
  525. }
  526. UA_TYPE_METHOD_DELETE_STRUCT(UA_LocalizedText)
  527. UA_Int32 UA_LocalizedText_deleteMembers(UA_LocalizedText* p) {
  528. return UA_SUCCESS
  529. || UA_String_deleteMembers(&(p->locale))
  530. || UA_String_deleteMembers(&(p->text))
  531. ;
  532. }
  533. UA_Int32 UA_LocalizedText_init(UA_LocalizedText* p){
  534. if(p==UA_NULL)return UA_ERROR;
  535. p->encodingMask = 0;
  536. UA_String_init(&(p->locale));
  537. UA_String_init(&(p->text));
  538. return UA_SUCCESS;
  539. }
  540. UA_TYPE_METHOD_NEW_DEFAULT(UA_LocalizedText)
  541. UA_Int32 UA_LocalizedText_copycstring(char const * src, UA_LocalizedText* dst) {
  542. UA_Int32 retval = UA_SUCCESS;
  543. if(dst==UA_NULL)return UA_ERROR;
  544. dst->encodingMask = UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE | UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
  545. retval |= UA_String_copycstring("EN",&(dst->locale));
  546. retval |= UA_String_copycstring(src,&(dst->text));
  547. return retval;
  548. }
  549. /* Serialization of UA_NodeID is specified in 62541-6, §5.2.2.9 */
  550. UA_Int32 UA_NodeId_calcSize(UA_NodeId const *p) {
  551. UA_Int32 length = 0;
  552. if (p == UA_NULL) {
  553. length = sizeof(UA_NodeId);
  554. } else {
  555. switch (p->encodingByte & UA_NODEIDTYPE_MASK) {
  556. case UA_NODEIDTYPE_TWOBYTE:
  557. length = 2;
  558. break;
  559. case UA_NODEIDTYPE_FOURBYTE:
  560. length = 4;
  561. break;
  562. case UA_NODEIDTYPE_NUMERIC:
  563. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + sizeof(UA_UInt32);
  564. break;
  565. case UA_NODEIDTYPE_STRING:
  566. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_String_calcSize(&(p->identifier.string));
  567. break;
  568. case UA_NODEIDTYPE_GUID:
  569. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_Guid_calcSize(&(p->identifier.guid));
  570. break;
  571. case UA_NODEIDTYPE_BYTESTRING:
  572. length += sizeof(UA_Byte) + sizeof(UA_UInt16) + UA_ByteString_calcSize(&(p->identifier.byteString));
  573. break;
  574. default:
  575. break;
  576. }
  577. }
  578. return length;
  579. }
  580. UA_Int32 UA_NodeId_encode(UA_NodeId const * src, UA_Int32* pos, UA_Byte* dst) {
  581. // temporary variables for endian-save code
  582. UA_Byte srcByte;
  583. UA_UInt16 srcUInt16;
  584. int retval = UA_SUCCESS;
  585. retval |= UA_Byte_encode(&(src->encodingByte),pos,dst);
  586. switch (src->encodingByte & UA_NODEIDTYPE_MASK) {
  587. case UA_NODEIDTYPE_TWOBYTE:
  588. srcByte = src->identifier.numeric;
  589. retval |= UA_Byte_encode(&srcByte,pos,dst);
  590. break;
  591. case UA_NODEIDTYPE_FOURBYTE:
  592. srcByte = src->namespace;
  593. srcUInt16 = src->identifier.numeric;
  594. retval |= UA_Byte_encode(&srcByte,pos,dst);
  595. retval |= UA_UInt16_encode(&srcUInt16,pos,dst);
  596. break;
  597. case UA_NODEIDTYPE_NUMERIC:
  598. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  599. retval |= UA_UInt32_encode(&(src->identifier.numeric), pos, dst);
  600. break;
  601. case UA_NODEIDTYPE_STRING:
  602. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  603. retval |= UA_String_encode(&(src->identifier.string), pos, dst);
  604. break;
  605. case UA_NODEIDTYPE_GUID:
  606. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  607. retval |= UA_Guid_encode(&(src->identifier.guid), pos, dst);
  608. break;
  609. case UA_NODEIDTYPE_BYTESTRING:
  610. retval |= UA_UInt16_encode(&(src->namespace), pos, dst);
  611. retval |= UA_ByteString_encode(&(src->identifier.byteString), pos, dst);
  612. break;
  613. }
  614. return retval;
  615. }
  616. UA_Int32 UA_NodeId_decode(UA_Byte const * src, UA_Int32* pos, UA_NodeId *dst) {
  617. int retval = UA_SUCCESS;
  618. // temporary variables to overcome decoder's non-endian-saveness for datatypes
  619. UA_Byte dstByte;
  620. UA_UInt16 dstUInt16;
  621. retval |= UA_Byte_decode(src,pos,&(dst->encodingByte));
  622. switch (dst->encodingByte & UA_NODEIDTYPE_MASK) {
  623. case UA_NODEIDTYPE_TWOBYTE: // Table 7
  624. retval |=UA_Byte_decode(src, pos, &dstByte);
  625. dst->identifier.numeric = dstByte;
  626. dst->namespace = 0; // default namespace
  627. break;
  628. case UA_NODEIDTYPE_FOURBYTE: // Table 8
  629. retval |=UA_Byte_decode(src, pos, &dstByte);
  630. dst->namespace= dstByte;
  631. retval |=UA_UInt16_decode(src, pos, &dstUInt16);
  632. dst->identifier.numeric = dstUInt16;
  633. break;
  634. case UA_NODEIDTYPE_NUMERIC: // Table 6, first entry
  635. retval |=UA_UInt16_decode(src,pos,&(dst->namespace));
  636. retval |=UA_UInt32_decode(src,pos,&(dst->identifier.numeric));
  637. break;
  638. case UA_NODEIDTYPE_STRING: // Table 6, second entry
  639. retval |=UA_UInt16_decode(src,pos,&(dst->namespace));
  640. retval |=UA_String_decode(src,pos,&(dst->identifier.string));
  641. break;
  642. case UA_NODEIDTYPE_GUID: // Table 6, third entry
  643. retval |=UA_UInt16_decode(src,pos,&(dst->namespace));
  644. retval |=UA_Guid_decode(src,pos,&(dst->identifier.guid));
  645. break;
  646. case UA_NODEIDTYPE_BYTESTRING: // Table 6, "OPAQUE"
  647. retval |=UA_UInt16_decode(src,pos,&(dst->namespace));
  648. retval |=UA_ByteString_decode(src,pos,&(dst->identifier.byteString));
  649. break;
  650. }
  651. return retval;
  652. }
  653. UA_TYPE_METHOD_DELETE_STRUCT(UA_NodeId)
  654. UA_Int32 UA_NodeId_deleteMembers(UA_NodeId* p) {
  655. int retval = UA_SUCCESS;
  656. switch (p->encodingByte & UA_NODEIDTYPE_MASK) {
  657. case UA_NODEIDTYPE_TWOBYTE:
  658. case UA_NODEIDTYPE_FOURBYTE:
  659. case UA_NODEIDTYPE_NUMERIC:
  660. // nothing to do
  661. break;
  662. case UA_NODEIDTYPE_STRING: // Table 6, second entry
  663. retval |= UA_String_deleteMembers(&(p->identifier.string));
  664. break;
  665. case UA_NODEIDTYPE_GUID: // Table 6, third entry
  666. retval |= UA_Guid_deleteMembers(&(p->identifier.guid));
  667. break;
  668. case UA_NODEIDTYPE_BYTESTRING: // Table 6, "OPAQUE"
  669. retval |= UA_ByteString_deleteMembers(&(p->identifier.byteString));
  670. break;
  671. }
  672. return retval;
  673. }
  674. void UA_NodeId_printf(char* label, UA_NodeId* node) {
  675. int l;
  676. printf("%s {encodingByte=%d, namespace=%d,", label,
  677. (int)( node->encodingByte), (int) (node->namespace));
  678. switch (node->encodingByte & UA_NODEIDTYPE_MASK) {
  679. case UA_NODEIDTYPE_TWOBYTE:
  680. case UA_NODEIDTYPE_FOURBYTE:
  681. case UA_NODEIDTYPE_NUMERIC:
  682. printf("identifier=%d\n", node->identifier.numeric);
  683. break;
  684. case UA_NODEIDTYPE_STRING:
  685. l = ( node->identifier.string.length < 0 ) ? 0 : node->identifier.string.length;
  686. printf("identifier={length=%d, data=%.*s}",
  687. node->identifier.string.length, l,
  688. (char*) (node->identifier.string.data));
  689. break;
  690. case UA_NODEIDTYPE_BYTESTRING:
  691. l = ( node->identifier.byteString.length < 0 ) ? 0 : node->identifier.byteString.length;
  692. printf("identifier={Length=%d, data=%.*s}",
  693. node->identifier.byteString.length, l,
  694. (char*) (node->identifier.byteString.data));
  695. break;
  696. case UA_NODEIDTYPE_GUID:
  697. printf(
  698. "guid={data1=%d, data2=%d, data3=%d, data4={length=%d, data=%.*s}}",
  699. node->identifier.guid.data1, node->identifier.guid.data2,
  700. node->identifier.guid.data3, 8,
  701. 8,
  702. (char*) (node->identifier.guid.data4));
  703. break;
  704. default:
  705. printf("ups! shit happens");
  706. break;
  707. }
  708. printf("}\n");
  709. }
  710. UA_Int32 UA_NodeId_compare(UA_NodeId *n1, UA_NodeId *n2) {
  711. if (n1->encodingByte != n2->encodingByte || n1->namespace != n2->namespace)
  712. return FALSE;
  713. switch (n1->encodingByte & UA_NODEIDTYPE_MASK) {
  714. case UA_NODEIDTYPE_TWOBYTE:
  715. case UA_NODEIDTYPE_FOURBYTE:
  716. case UA_NODEIDTYPE_NUMERIC:
  717. if(n1->identifier.numeric == n2->identifier.numeric)
  718. return UA_EQUAL;
  719. else
  720. return UA_NOT_EQUAL;
  721. case UA_NODEIDTYPE_STRING:
  722. return UA_String_compare(&(n1->identifier.string), &(n2->identifier.string));
  723. case UA_NODEIDTYPE_GUID:
  724. return UA_Guid_compare(&(n1->identifier.guid), &(n2->identifier.guid));
  725. case UA_NODEIDTYPE_BYTESTRING:
  726. return UA_ByteString_compare(&(n1->identifier.byteString), &(n2->identifier.byteString));
  727. }
  728. return UA_NOT_EQUAL;
  729. }
  730. UA_Int32 UA_NodeId_init(UA_NodeId* p){
  731. if(p==UA_NULL)return UA_ERROR;
  732. p->encodingByte = 0;
  733. p->identifier.numeric = 0;
  734. p->namespace = 0;
  735. return UA_SUCCESS;
  736. }
  737. UA_TYPE_METHOD_NEW_DEFAULT(UA_NodeId)
  738. UA_Int32 UA_ExpandedNodeId_calcSize(UA_ExpandedNodeId const * p) {
  739. UA_Int32 length = 0;
  740. if (p == UA_NULL) {
  741. length = sizeof(UA_ExpandedNodeId);
  742. } else {
  743. length = UA_NodeId_calcSize(&(p->nodeId));
  744. if (p->nodeId.encodingByte & UA_NODEIDTYPE_NAMESPACE_URI_FLAG) {
  745. length += UA_String_calcSize(&(p->namespaceUri)); //p->namespaceUri
  746. }
  747. if (p->nodeId.encodingByte & UA_NODEIDTYPE_SERVERINDEX_FLAG) {
  748. length += sizeof(UA_UInt32); //p->serverIndex
  749. }
  750. }
  751. return length;
  752. }
  753. UA_Int32 UA_ExpandedNodeId_encode(UA_ExpandedNodeId const * src, UA_Int32* pos, UA_Byte* dst) {
  754. UA_UInt32 retval = UA_SUCCESS;
  755. retval |= UA_NodeId_encode(&(src->nodeId),pos,dst);
  756. if (src->nodeId.encodingByte & UA_NODEIDTYPE_NAMESPACE_URI_FLAG) {
  757. retval |= UA_String_encode(&(src->namespaceUri),pos,dst);
  758. }
  759. if (src->nodeId.encodingByte & UA_NODEIDTYPE_SERVERINDEX_FLAG) {
  760. retval |= UA_UInt32_encode(&(src->serverIndex),pos,dst);
  761. }
  762. return retval;
  763. }
  764. UA_Int32 UA_ExpandedNodeId_decode(UA_Byte const * src, UA_Int32* pos,
  765. UA_ExpandedNodeId *dst) {
  766. UA_UInt32 retval = UA_SUCCESS;
  767. retval |= UA_NodeId_decode(src,pos,&(dst->nodeId));
  768. if (dst->nodeId.encodingByte & UA_NODEIDTYPE_NAMESPACE_URI_FLAG) {
  769. dst->nodeId.namespace = 0;
  770. retval |= UA_String_decode(src,pos,&(dst->namespaceUri));
  771. } else {
  772. retval |= UA_String_copy(&UA_String_null, &(dst->namespaceUri));
  773. }
  774. if (dst->nodeId.encodingByte & UA_NODEIDTYPE_SERVERINDEX_FLAG) {
  775. retval |= UA_UInt32_decode(src,pos,&(dst->serverIndex));
  776. }
  777. return retval;
  778. }
  779. UA_TYPE_METHOD_DELETE_STRUCT(UA_ExpandedNodeId)
  780. UA_Int32 UA_ExpandedNodeId_deleteMembers(UA_ExpandedNodeId* p) {
  781. UA_Int32 retval = UA_SUCCESS;
  782. retval |= UA_NodeId_deleteMembers(&(p->nodeId));
  783. retval |= UA_String_deleteMembers(&(p->namespaceUri));
  784. return retval;
  785. }
  786. UA_Int32 UA_ExpandedNodeId_init(UA_ExpandedNodeId* p){
  787. if(p==UA_NULL)return UA_ERROR;
  788. UA_String_init(&(p->namespaceUri));
  789. return UA_SUCCESS;
  790. }
  791. UA_TYPE_METHOD_NEW_DEFAULT(UA_ExpandedNodeId)
  792. UA_Int32 UA_ExtensionObject_calcSize(UA_ExtensionObject const * p) {
  793. UA_Int32 length = 0;
  794. if (p == UA_NULL) {
  795. length = sizeof(UA_ExtensionObject);
  796. } else {
  797. length += UA_NodeId_calcSize(&(p->typeId));
  798. length += 1; //p->encoding
  799. switch (p->encoding) {
  800. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_BODYISBYTESTRING:
  801. length += UA_ByteString_calcSize(&(p->body));
  802. break;
  803. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_BODYISXML:
  804. length += UA_XmlElement_calcSize((UA_XmlElement*)&(p->body));
  805. break;
  806. }
  807. }
  808. return length;
  809. }
  810. UA_Int32 UA_ExtensionObject_encode(UA_ExtensionObject const *src, UA_Int32* pos, UA_Byte * dst) {
  811. UA_Int32 retval = UA_SUCCESS;
  812. retval |= UA_NodeId_encode(&(src->typeId),pos,dst);
  813. retval |= UA_Byte_encode(&(src->encoding),pos,dst);
  814. switch (src->encoding) {
  815. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_NOBODYISENCODED:
  816. break;
  817. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_BODYISBYTESTRING:
  818. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_BODYISXML:
  819. retval |= UA_ByteString_encode(&(src->body),pos,dst);
  820. break;
  821. }
  822. return retval;
  823. }
  824. UA_Int32 UA_ExtensionObject_decode(UA_Byte const * src, UA_Int32 *pos,
  825. UA_ExtensionObject *dst) {
  826. UA_Int32 retval = UA_SUCCESS;
  827. retval |= UA_NodeId_decode(src,pos,&(dst->typeId));
  828. retval |= UA_Byte_decode(src,pos,&(dst->encoding));
  829. retval |= UA_String_copy(&UA_String_null, (UA_String*) &(dst->body));
  830. switch (dst->encoding) {
  831. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_NOBODYISENCODED:
  832. break;
  833. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_BODYISBYTESTRING:
  834. case UA_EXTENSIONOBJECT_ENCODINGMASKTYPE_BODYISXML:
  835. retval |= UA_ByteString_decode(src,pos,&(dst->body));
  836. break;
  837. }
  838. return retval;
  839. }
  840. UA_TYPE_METHOD_DELETE_STRUCT(UA_ExtensionObject)
  841. UA_Int32 UA_ExtensionObject_deleteMembers(UA_ExtensionObject *p) {
  842. UA_Int32 retval = UA_SUCCESS;
  843. retval |= UA_NodeId_deleteMembers(&(p->typeId));
  844. retval |= UA_ByteString_deleteMembers(&(p->body));
  845. return retval;
  846. }
  847. UA_Int32 UA_ExtensionObject_init(UA_ExtensionObject* p){
  848. if(p==UA_NULL)return UA_ERROR;
  849. UA_ByteString_init(&(p->body));
  850. p->encoding = 0;
  851. UA_NodeId_init(&(p->typeId));
  852. return UA_SUCCESS;
  853. }
  854. UA_TYPE_METHOD_NEW_DEFAULT(UA_ExtensionObject)
  855. /** DiagnosticInfo - Part: 4, Chapter: 7.9, Page: 116 */
  856. UA_Int32 UA_DiagnosticInfo_decode(UA_Byte const * src, UA_Int32 *pos, UA_DiagnosticInfo *dst) {
  857. UA_Int32 retval = UA_SUCCESS;
  858. int i;
  859. retval |= UA_Byte_decode(src, pos, &(dst->encodingMask));
  860. for (i = 0; i < 7; i++) {
  861. switch ( (0x01 << i) & dst->encodingMask) {
  862. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_SYMBOLICID:
  863. retval |= UA_Int32_decode(src, pos, &(dst->symbolicId));
  864. break;
  865. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_NAMESPACE:
  866. retval |= UA_Int32_decode(src, pos, &(dst->namespaceUri));
  867. break;
  868. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_LOCALIZEDTEXT:
  869. retval |= UA_Int32_decode(src, pos, &(dst->localizedText));
  870. break;
  871. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_LOCALE:
  872. retval |= UA_Int32_decode(src, pos, &(dst->locale));
  873. break;
  874. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_ADDITIONALINFO:
  875. retval |= UA_String_decode(src, pos, &(dst->additionalInfo));
  876. break;
  877. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERSTATUSCODE:
  878. retval |= UA_StatusCode_decode(src, pos, &(dst->innerStatusCode));
  879. break;
  880. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERDIAGNOSTICINFO:
  881. // innerDiagnosticInfo is a pointer to struct, therefore allocate
  882. retval |= UA_alloc((void **) &(dst->innerDiagnosticInfo),UA_DiagnosticInfo_calcSize(UA_NULL));
  883. retval |= UA_DiagnosticInfo_decode(src, pos, dst->innerDiagnosticInfo);
  884. break;
  885. }
  886. }
  887. return retval;
  888. }
  889. UA_Int32 UA_DiagnosticInfo_encode(UA_DiagnosticInfo const *src, UA_Int32 *pos, UA_Byte* dst) {
  890. UA_Int32 retval = UA_SUCCESS;
  891. int i;
  892. UA_Byte_encode(&(src->encodingMask), pos, dst);
  893. for (i = 0; i < 7; i++) {
  894. switch ( (0x01 << i) & src->encodingMask) {
  895. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_SYMBOLICID:
  896. retval |= UA_Int32_encode(&(src->symbolicId), pos, dst);
  897. break;
  898. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_NAMESPACE:
  899. retval |= UA_Int32_encode( &(src->namespaceUri), pos, dst);
  900. break;
  901. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_LOCALIZEDTEXT:
  902. retval |= UA_Int32_encode(&(src->localizedText), pos, dst);
  903. break;
  904. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_LOCALE:
  905. retval |= UA_Int32_encode(&(src->locale), pos, dst);
  906. break;
  907. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_ADDITIONALINFO:
  908. retval |= UA_String_encode(&(src->additionalInfo), pos, dst);
  909. break;
  910. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERSTATUSCODE:
  911. retval |= UA_StatusCode_encode(&(src->innerStatusCode), pos, dst);
  912. break;
  913. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERDIAGNOSTICINFO:
  914. retval |= UA_DiagnosticInfo_encode(src->innerDiagnosticInfo, pos, dst);
  915. break;
  916. }
  917. }
  918. return retval;
  919. }
  920. UA_Int32 UA_DiagnosticInfo_calcSize(UA_DiagnosticInfo const * ptr) {
  921. UA_Int32 length = 0;
  922. if (ptr == UA_NULL) {
  923. length = sizeof(UA_DiagnosticInfo);
  924. } else {
  925. UA_Byte mask;
  926. length += sizeof(UA_Byte); // EncodingMask
  927. for (mask = 0x01; mask <= 0x40; mask *= 2) {
  928. switch (mask & (ptr->encodingMask)) {
  929. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_SYMBOLICID:
  930. // puts("diagnosticInfo symbolic id");
  931. length += sizeof(UA_Int32);
  932. break;
  933. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_NAMESPACE:
  934. length += sizeof(UA_Int32);
  935. break;
  936. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_LOCALIZEDTEXT:
  937. length += sizeof(UA_Int32);
  938. break;
  939. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_LOCALE:
  940. length += sizeof(UA_Int32);
  941. break;
  942. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_ADDITIONALINFO:
  943. length += UA_String_calcSize(&(ptr->additionalInfo));
  944. break;
  945. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERSTATUSCODE:
  946. length += sizeof(UA_StatusCode);
  947. break;
  948. case UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERDIAGNOSTICINFO:
  949. length += UA_DiagnosticInfo_calcSize(ptr->innerDiagnosticInfo);
  950. break;
  951. }
  952. }
  953. }
  954. return length;
  955. }
  956. UA_TYPE_METHOD_DELETE_STRUCT(UA_DiagnosticInfo)
  957. UA_Int32 UA_DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p) {
  958. UA_Int32 retval = UA_SUCCESS;
  959. if (p->encodingMask & UA_DIAGNOSTICINFO_ENCODINGMASKTYPE_INNERDIAGNOSTICINFO) {
  960. retval |= UA_DiagnosticInfo_deleteMembers(p->innerDiagnosticInfo);
  961. retval |= UA_free(p->innerDiagnosticInfo);
  962. }
  963. return retval;
  964. }
  965. UA_Int32 UA_DiagnosticInfo_init(UA_DiagnosticInfo* p){
  966. if(p==UA_NULL)return UA_ERROR;
  967. UA_String_init(&(p->additionalInfo));
  968. p->encodingMask = 0;
  969. p->innerDiagnosticInfo = UA_NULL;
  970. UA_StatusCode_init(&(p->innerStatusCode));
  971. p->locale = 0;
  972. p->localizedText = 0;
  973. p->namespaceUri = 0;
  974. p->symbolicId = 0;
  975. return UA_SUCCESS;
  976. }
  977. UA_TYPE_METHOD_NEW_DEFAULT(UA_DiagnosticInfo)
  978. UA_TYPE_METHOD_CALCSIZE_SIZEOF(UA_DateTime)
  979. UA_TYPE_METHOD_ENCODE_AS(UA_DateTime,UA_Int64)
  980. UA_TYPE_METHOD_DECODE_AS(UA_DateTime,UA_Int64)
  981. UA_TYPE_METHOD_DELETE_FREE(UA_DateTime)
  982. UA_TYPE_METHOD_DELETEMEMBERS_NOACTION(UA_DateTime)
  983. UA_TYPE_METHOD_INIT_AS(UA_DateTime,UA_Int64)
  984. UA_TYPE_METHOD_NEW_DEFAULT(UA_DateTime)
  985. #include <sys/time.h>
  986. // Number of seconds from 1 Jan. 1601 00:00 to 1 Jan 1970 00:00 UTC
  987. #define FILETIME_UNIXTIME_BIAS_SEC 11644473600LL
  988. // Factors
  989. #define HUNDRED_NANOSEC_PER_USEC 10LL
  990. #define HUNDRED_NANOSEC_PER_SEC (HUNDRED_NANOSEC_PER_USEC * 1000000LL)
  991. // IEC 62541-6 §5.2.2.5 A DateTime value shall be encoded as a 64-bit signed integer
  992. // which represents the number of 100 nanosecond intervals since January 1, 1601 (UTC).
  993. UA_DateTime UA_DateTime_now() {
  994. UA_DateTime dateTime;
  995. struct timeval tv;
  996. gettimeofday(&tv, UA_NULL);
  997. dateTime = (tv.tv_sec + FILETIME_UNIXTIME_BIAS_SEC)
  998. * HUNDRED_NANOSEC_PER_SEC + tv.tv_usec * HUNDRED_NANOSEC_PER_USEC;
  999. return dateTime;
  1000. }
  1001. UA_TYPE_METHOD_CALCSIZE_AS(UA_XmlElement, UA_ByteString)
  1002. UA_TYPE_METHOD_ENCODE_AS(UA_XmlElement, UA_ByteString)
  1003. UA_TYPE_METHOD_DECODE_AS(UA_XmlElement, UA_ByteString)
  1004. UA_TYPE_METHOD_DELETE_AS(UA_XmlElement, UA_ByteString)
  1005. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_XmlElement, UA_ByteString)
  1006. UA_TYPE_METHOD_INIT_AS(UA_XmlElement, UA_ByteString)
  1007. UA_TYPE_METHOD_NEW_DEFAULT(UA_XmlElement)
  1008. /** IntegerId - Part: 4, Chapter: 7.13, Page: 118 */
  1009. UA_TYPE_METHOD_CALCSIZE_AS(UA_IntegerId, UA_Int32)
  1010. UA_TYPE_METHOD_ENCODE_AS(UA_IntegerId, UA_Int32)
  1011. UA_TYPE_METHOD_DECODE_AS(UA_IntegerId, UA_Int32)
  1012. UA_TYPE_METHOD_DELETE_AS(UA_IntegerId, UA_Int32)
  1013. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_IntegerId, UA_Int32)
  1014. UA_TYPE_METHOD_INIT_AS(UA_IntegerId, UA_Int32)
  1015. UA_TYPE_METHOD_NEW_DEFAULT(UA_IntegerId)
  1016. UA_TYPE_METHOD_CALCSIZE_AS(UA_StatusCode, UA_UInt32)
  1017. UA_TYPE_METHOD_ENCODE_AS(UA_StatusCode, UA_UInt32)
  1018. UA_TYPE_METHOD_DECODE_AS(UA_StatusCode, UA_UInt32)
  1019. UA_TYPE_METHOD_DELETE_AS(UA_StatusCode, UA_UInt32)
  1020. UA_TYPE_METHOD_DELETEMEMBERS_AS(UA_StatusCode, UA_UInt32)
  1021. UA_TYPE_METHOD_INIT_AS(UA_StatusCode, UA_Int32)
  1022. UA_TYPE_METHOD_NEW_DEFAULT(UA_StatusCode)
  1023. UA_Int32 UA_QualifiedName_calcSize(UA_QualifiedName const * p) {
  1024. UA_Int32 length = 0;
  1025. if (p == NULL) return sizeof(UA_QualifiedName);
  1026. length += sizeof(UA_UInt16); //qualifiedName->namespaceIndex
  1027. length += sizeof(UA_UInt16); //qualifiedName->reserved
  1028. length += UA_String_calcSize(&(p->name)); //qualifiedName->name
  1029. return length;
  1030. }
  1031. UA_Int32 UA_QualifiedName_decode(UA_Byte const * src, UA_Int32 *pos,
  1032. UA_QualifiedName *dst) {
  1033. UA_Int32 retval = UA_SUCCESS;
  1034. retval |= UA_UInt16_decode(src,pos,&(dst->namespaceIndex));
  1035. retval |= UA_UInt16_decode(src,pos,&(dst->reserved));
  1036. retval |= UA_String_decode(src,pos,&(dst->name));
  1037. return retval;
  1038. }
  1039. UA_Int32 UA_QualifiedName_encode(UA_QualifiedName const *src, UA_Int32* pos,
  1040. UA_Byte *dst) {
  1041. UA_Int32 retval = UA_SUCCESS;
  1042. retval |= UA_UInt16_encode(&(src->namespaceIndex),pos,dst);
  1043. retval |= UA_UInt16_encode(&(src->reserved),pos,dst);
  1044. retval |= UA_String_encode(&(src->name),pos,dst);
  1045. return retval;
  1046. }
  1047. UA_Int32 UA_QualifiedName_delete(UA_QualifiedName * p) {
  1048. UA_Int32 retval = UA_SUCCESS;
  1049. retval |= UA_QualifiedName_deleteMembers(p);
  1050. retval |= UA_free(p);
  1051. return retval;
  1052. }
  1053. UA_Int32 UA_QualifiedName_deleteMembers(UA_QualifiedName * p) {
  1054. UA_Int32 retval = UA_SUCCESS;
  1055. retval |= UA_String_deleteMembers(&(p->name));
  1056. return retval;
  1057. }
  1058. UA_Int32 UA_QualifiedName_init(UA_QualifiedName * p){
  1059. if(p==UA_NULL)return UA_ERROR;
  1060. UA_String_init(&(p->name));
  1061. p->namespaceIndex=0;
  1062. p->reserved=0;
  1063. return UA_SUCCESS;
  1064. }
  1065. UA_TYPE_METHOD_NEW_DEFAULT(UA_QualifiedName)
  1066. UA_Int32 UA_Variant_calcSize(UA_Variant const * p) {
  1067. UA_Int32 length = 0;
  1068. if (p == UA_NULL) return sizeof(UA_Variant);
  1069. UA_UInt32 ns0Id = p->encodingMask & 0x1F; // Bits 1-5
  1070. UA_Boolean isArray = p->encodingMask & (0x01 << 7); // Bit 7
  1071. UA_Boolean hasDimensions = p->encodingMask & (0x01 << 6); // Bit 6
  1072. int i;
  1073. if (p->vt == UA_NULL || ns0Id != p->vt->Id) {
  1074. return UA_ERR_INCONSISTENT;
  1075. }
  1076. length += sizeof(UA_Byte); //p->encodingMask
  1077. if (isArray) { // array length is encoded
  1078. length += sizeof(UA_Int32); //p->arrayLength
  1079. if (p->arrayLength > 0) {
  1080. // TODO: add suggestions of @jfpr to not iterate over arrays with fixed len elements
  1081. // FIXME: the concept of calcSize delivering the storageSize given an UA_Null argument
  1082. // fails for arrays with null-ptrs, see test case
  1083. // UA_Variant_calcSizeVariableSizeArrayWithNullPtrWillReturnWrongEncodingSize
  1084. // Simply do not allow?
  1085. for (i=0;i<p->arrayLength;i++) {
  1086. length += p->vt->calcSize(p->data[i]);
  1087. }
  1088. }
  1089. } else { //single value to encode
  1090. length += p->vt->calcSize(p->data[0]);
  1091. }
  1092. if (hasDimensions) {
  1093. //ToDo: tobeInsert: length += the calcSize for dimensions
  1094. }
  1095. return length;
  1096. }
  1097. UA_Int32 UA_Variant_encode(UA_Variant const *src, UA_Int32* pos, UA_Byte *dst) {
  1098. UA_Int32 retval = UA_SUCCESS;
  1099. int i = 0;
  1100. if (src->vt == UA_NULL || ( src->encodingMask & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) != src->vt->Id) {
  1101. return UA_ERR_INCONSISTENT;
  1102. }
  1103. retval |= UA_Byte_encode(&(src->encodingMask),pos,dst);
  1104. if (src->encodingMask & UA_VARIANT_ENCODINGMASKTYPE_ARRAY) { // encode array length
  1105. retval |= UA_Int32_encode(&(src->arrayLength),pos,dst);
  1106. }
  1107. if (src->arrayLength > 0) {
  1108. //encode array as given by variant type
  1109. for (i=0;i<src->arrayLength;i++) {
  1110. retval |= src->vt->encode(src->data[i],pos,dst);
  1111. }
  1112. } else {
  1113. retval |= src->vt->encode(src->data[i],pos,dst);
  1114. }
  1115. if (src->encodingMask & UA_VARIANT_ENCODINGMASKTYPE_ARRAY) { // encode array dimension field
  1116. // TODO: encode array dimension field
  1117. }
  1118. return retval;
  1119. }
  1120. UA_Int32 UA_Variant_decode(UA_Byte const * src, UA_Int32 *pos, UA_Variant *dst) {
  1121. UA_Int32 retval = UA_SUCCESS;
  1122. UA_Int32 ns0Id;
  1123. retval |= UA_Byte_decode(src,pos,&(dst->encodingMask));
  1124. ns0Id = dst->encodingMask & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK;
  1125. // initialize vTable
  1126. if (ns0Id < UA_BOOLEAN && ns0Id > UA_DOUBLECOMPLEXNUMBERTYPE) {
  1127. return UA_ERR_INVALID_VALUE;
  1128. } else {
  1129. dst->vt = &UA_[UA_toIndex(ns0Id)];
  1130. }
  1131. // get size of array
  1132. if (dst->encodingMask & UA_VARIANT_ENCODINGMASKTYPE_ARRAY) { // encode array length
  1133. retval |= UA_Int32_decode(src,pos,&(dst->arrayLength));
  1134. } else {
  1135. dst->arrayLength = 1;
  1136. }
  1137. // allocate array and decode
  1138. retval |= UA_Array_new((void**)&(dst->data),dst->arrayLength,UA_toIndex(ns0Id));
  1139. retval |= UA_Array_decode(src,dst->arrayLength,UA_toIndex(ns0Id),pos,dst->data);
  1140. if (dst->encodingMask & UA_VARIANT_ENCODINGMASKTYPE_DIMENSIONS) {
  1141. // TODO: decode array dimension field
  1142. }
  1143. return retval;
  1144. }
  1145. UA_TYPE_METHOD_DELETE_STRUCT(UA_Variant)
  1146. UA_Int32 UA_Variant_deleteMembers(UA_Variant * p) {
  1147. UA_Int32 retval = UA_SUCCESS;
  1148. retval |= UA_Array_delete(p->data,p->arrayLength,UA_toIndex(p->vt->Id));
  1149. return retval;
  1150. }
  1151. UA_Int32 UA_Variant_init(UA_Variant * p){
  1152. if(p==UA_NULL)return UA_ERROR;
  1153. p->arrayLength = 0;
  1154. p->data = UA_NULL;
  1155. p->encodingMask = 0;
  1156. p->vt = UA_NULL;
  1157. return UA_SUCCESS;
  1158. }
  1159. UA_TYPE_METHOD_NEW_DEFAULT(UA_Variant)
  1160. //TODO: place this define at the server configuration
  1161. #define MAX_PICO_SECONDS 1000
  1162. UA_Int32 UA_DataValue_decode(UA_Byte const * src, UA_Int32* pos, UA_DataValue* dst) {
  1163. UA_Int32 retval = UA_SUCCESS;
  1164. retval |= UA_Byte_decode(src,pos,&(dst->encodingMask));
  1165. if (dst->encodingMask & UA_DATAVALUE_VARIANT) {
  1166. retval |= UA_Variant_decode(src,pos,&(dst->value));
  1167. }
  1168. if (dst->encodingMask & UA_DATAVALUE_STATUSCODE) {
  1169. retval |= UA_StatusCode_decode(src,pos,&(dst->status));
  1170. }
  1171. if (dst->encodingMask & UA_DATAVALUE_SOURCETIMESTAMP) {
  1172. retval |= UA_DateTime_decode(src,pos,&(dst->sourceTimestamp));
  1173. }
  1174. if (dst->encodingMask & UA_DATAVALUE_SOURCEPICOSECONDS) {
  1175. retval |= UA_Int16_decode(src,pos,&(dst->sourcePicoseconds));
  1176. if (dst->sourcePicoseconds > MAX_PICO_SECONDS) {
  1177. dst->sourcePicoseconds = MAX_PICO_SECONDS;
  1178. }
  1179. }
  1180. if (dst->encodingMask & UA_DATAVALUE_SERVERTIMPSTAMP) {
  1181. retval |= UA_DateTime_decode(src,pos,&(dst->serverTimestamp));
  1182. }
  1183. if (dst->encodingMask & UA_DATAVALUE_SERVERPICOSECONDS) {
  1184. retval |= UA_Int16_decode(src,pos,&(dst->serverPicoseconds));
  1185. if (dst->serverPicoseconds > MAX_PICO_SECONDS) {
  1186. dst->serverPicoseconds = MAX_PICO_SECONDS;
  1187. }
  1188. }
  1189. return retval;
  1190. }
  1191. UA_Int32 UA_DataValue_encode(UA_DataValue const * src, UA_Int32* pos, UA_Byte*dst) {
  1192. UA_Int32 retval = UA_SUCCESS;
  1193. retval |= UA_Byte_encode(&(src->encodingMask),pos,dst);
  1194. if (src->encodingMask & UA_DATAVALUE_VARIANT) {
  1195. retval |= UA_Variant_encode(&(src->value),pos,dst);
  1196. }
  1197. if (src->encodingMask & UA_DATAVALUE_STATUSCODE) {
  1198. retval |= UA_StatusCode_encode(&(src->status),pos,dst);
  1199. }
  1200. if (src->encodingMask & UA_DATAVALUE_SOURCETIMESTAMP) {
  1201. retval |= UA_DateTime_encode(&(src->sourceTimestamp),pos,dst);
  1202. }
  1203. if (src->encodingMask & UA_DATAVALUE_SOURCEPICOSECONDS) {
  1204. retval |= UA_Int16_encode(&(src->sourcePicoseconds),pos,dst);
  1205. }
  1206. if (src->encodingMask & UA_DATAVALUE_SERVERTIMPSTAMP) {
  1207. retval |= UA_DateTime_encode(&(src->serverTimestamp),pos,dst);
  1208. }
  1209. if (src->encodingMask & UA_DATAVALUE_SERVERPICOSECONDS) {
  1210. retval |= UA_Int16_encode(&(src->serverPicoseconds),pos,dst);
  1211. }
  1212. return retval;
  1213. }
  1214. UA_Int32 UA_DataValue_calcSize(UA_DataValue const * p) {
  1215. UA_Int32 length = 0;
  1216. if (p == UA_NULL) { // get static storage size
  1217. length = sizeof(UA_DataValue);
  1218. } else { // get decoding size
  1219. length = sizeof(UA_Byte);
  1220. if (p->encodingMask & UA_DATAVALUE_VARIANT) {
  1221. length += UA_Variant_calcSize(&(p->value));
  1222. }
  1223. if (p->encodingMask & UA_DATAVALUE_STATUSCODE) {
  1224. length += sizeof(UA_UInt32); //dataValue->status
  1225. }
  1226. if (p->encodingMask & UA_DATAVALUE_SOURCETIMESTAMP) {
  1227. length += sizeof(UA_DateTime); //dataValue->sourceTimestamp
  1228. }
  1229. if (p->encodingMask & UA_DATAVALUE_SOURCEPICOSECONDS) {
  1230. length += sizeof(UA_Int64); //dataValue->sourcePicoseconds
  1231. }
  1232. if (p->encodingMask & UA_DATAVALUE_SERVERTIMPSTAMP) {
  1233. length += sizeof(UA_DateTime); //dataValue->serverTimestamp
  1234. }
  1235. if (p->encodingMask & UA_DATAVALUE_SERVERPICOSECONDS) {
  1236. length += sizeof(UA_Int64); //dataValue->serverPicoseconds
  1237. }
  1238. }
  1239. return length;
  1240. }
  1241. UA_TYPE_METHOD_DELETE_STRUCT(UA_DataValue)
  1242. UA_Int32 UA_DataValue_deleteMembers(UA_DataValue * p) {
  1243. UA_Int32 retval = UA_SUCCESS;
  1244. UA_Variant_deleteMembers(&(p->value));
  1245. return retval;
  1246. }
  1247. UA_Int32 UA_DataValue_init(UA_DataValue * p){
  1248. if(p==UA_NULL)return UA_ERROR;
  1249. p->encodingMask = 0;
  1250. p->serverPicoseconds = 0;
  1251. UA_DateTime_init(&(p->serverTimestamp));
  1252. p->sourcePicoseconds = 0;
  1253. UA_DateTime_init(&(p->sourceTimestamp));
  1254. UA_StatusCode_init(&(p->status));
  1255. UA_Variant_init(&(p->value));
  1256. return UA_SUCCESS;
  1257. }
  1258. UA_TYPE_METHOD_NEW_DEFAULT(UA_DataValue)