1
0

main_codec.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. * Copyright (C) 2007-2012 Siemens AG
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License as published
  6. * by the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU Lesser General Public License for more details.
  13. * GNU Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*******************************************************************
  19. *
  20. * @author Daniel.Peintner.EXT@siemens.com
  21. * @version 0.6
  22. * @contact Joerg.Heuer@siemens.com
  23. *
  24. * <p>Code generated by EXIdizer</p>
  25. ********************************************************************/
  26. /*******************************************************************
  27. *
  28. * <p>Sample program to illustrate how to read an EXI stream and
  29. * directly write it again to an output</p>
  30. *
  31. * <p>e.g., data/test/sessionSetupReq.xml.exi out/test/sessionSetupReq.xml.exi</p>
  32. ********************************************************************/
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include "EXIDecoder.h"
  36. #include "StringTable.h"
  37. #include "EXIEncoder.h"
  38. #include "EXITypes.h"
  39. #include "ByteStream.h"
  40. #if EXI_STREAM == BYTE_ARRAY
  41. /* 64 kilobytes = 65 536 bytes */
  42. /* 1 megabyte = 1 048 576 bytes*/
  43. #define BUFFER_SIZE 1048576
  44. uint8_t bufferIn[BUFFER_SIZE];
  45. uint8_t bufferOut[BUFFER_SIZE];
  46. #endif /* EXI_STREAM == BYTE_ARRAY */
  47. /* avoids warning: initializer element is not computable at load time */
  48. #define ARRAY_SIZE_BYTES 300
  49. uint8_t bytesData[ARRAY_SIZE_BYTES];
  50. #define ARRAY_SIZE_STRINGS 30000
  51. uint32_t codepoints[ARRAY_SIZE_STRINGS];
  52. #define ARRAY_SIZE_STRINGS_ASCII 150
  53. char charsNamespaceURI[ARRAY_SIZE_STRINGS_ASCII];
  54. char charsLocalName[ARRAY_SIZE_STRINGS_ASCII];
  55. #if EXI_DEBUG == EXI_DEBUG_ON
  56. static void debugValue(exi_value_t* val);
  57. #endif /*EXI_DEBUG*/
  58. int xmain(int argc, char *argv[]) {
  59. int errn = 0;
  60. unsigned int k;
  61. bitstream_t iStream, oStream;
  62. uint32_t posDecode;
  63. uint32_t posEncode;
  64. /* EXI set-up */
  65. exi_state_t stateDecode;
  66. exi_state_t stateEncode;
  67. exi_event_t event;
  68. eqname_t eqn; /* efficient qname */
  69. qname_t qn; /* ascii qname */
  70. exi_value_t val;
  71. exi_name_table_runtime_t runtimeTableDecode;
  72. exi_name_table_runtime_t runtimeTableEncode;
  73. /* BINARY memory setup */
  74. bytes_t bytes = { ARRAY_SIZE_BYTES, bytesData, 0 };
  75. #if EXI_DEBUG == EXI_DEBUG_ON
  76. const char * localName;
  77. const char * namespaceURI;
  78. #endif /*EXI_DEBUG*/
  79. int noEndOfDocument = 1; /* true */
  80. /* STRING memory setup */
  81. string_ucs_t string = { ARRAY_SIZE_STRINGS, codepoints, 0 };
  82. string_ascii_t stringNamespaceURI = { ARRAY_SIZE_STRINGS_ASCII,
  83. charsNamespaceURI };
  84. string_ascii_t stringLocalName =
  85. { ARRAY_SIZE_STRINGS_ASCII, charsLocalName };
  86. qn.namespaceURI = stringNamespaceURI;
  87. qn.localName = stringLocalName;
  88. if (argc != 3) {
  89. printf("Usage: %s exiInput exiOutput\n", argv[0]);
  90. return -1;
  91. }
  92. /* input pos */
  93. posDecode = 0;
  94. #if EXI_STREAM == BYTE_ARRAY
  95. /* parse EXI stream to internal byte structures */
  96. errn = readBytesFromFile(argv[1], bufferIn, BUFFER_SIZE, posDecode);
  97. if (errn < 0) {
  98. printf("Problems while reading file into buffer\n");
  99. return errn;
  100. }
  101. #endif /* EXI_STREAM == BYTE_ARRAY */
  102. /* setup input stream */
  103. #if EXI_STREAM == BYTE_ARRAY
  104. iStream.size = BUFFER_SIZE;
  105. iStream.data = bufferIn;
  106. iStream.pos = &posDecode;
  107. #endif /* EXI_STREAM == BYTE_ARRAY */
  108. #if EXI_STREAM == FILE_STREAM
  109. iStream.file = fopen(argv[1], "rb");
  110. #endif /* EXI_STREAM == FILE_STREAM */
  111. iStream.buffer = 0;
  112. iStream.capacity = 0;
  113. /* setup output stream */
  114. posEncode = 0;
  115. #if EXI_STREAM == BYTE_ARRAY
  116. oStream.size = BUFFER_SIZE;
  117. oStream.data = bufferOut;
  118. oStream.pos = &posEncode;
  119. #endif
  120. #if EXI_STREAM == FILE_STREAM
  121. oStream.file = fopen(argv[2], "wb");
  122. #endif /* EXI_STREAM == FILE_STREAM */
  123. oStream.buffer = 0;
  124. oStream.capacity = 8;
  125. val.binary = bytes;
  126. val.string = string;
  127. /* init decoder (read header, set initial state) */
  128. /* init runtime table */
  129. errn = exiInitNameTableRuntime(&runtimeTableDecode);
  130. exiInitDecoder(&iStream, &stateDecode, runtimeTableDecode);
  131. /* init encoder (write header, set initial state) */
  132. errn = exiInitNameTableRuntime(&runtimeTableEncode);
  133. exiInitEncoder(&oStream, &stateEncode, runtimeTableEncode);
  134. #if EXI_DEBUG == EXI_DEBUG_ON
  135. printf("[DECODE] >>> EXI >>> [ENCODE] \n");
  136. #endif /*EXI_DEBUG*/
  137. do {
  138. if (errn < 0) {
  139. #if EXI_DEBUG == EXI_DEBUG_ON
  140. printf("[Encode-ERROR] %d \n", errn);
  141. #endif /*EXI_DEBUG*/
  142. return errn;
  143. }
  144. errn = exiDecodeNextEvent(&iStream, &stateDecode,
  145. &event);
  146. if (errn < 0) {
  147. #if EXI_DEBUG == EXI_DEBUG_ON
  148. printf("[Decode-ERROR] %d \n", errn);
  149. #endif /*EXI_DEBUG*/
  150. return errn;
  151. }
  152. switch (event) {
  153. case EXI_EVENT_START_DOCUMENT:
  154. /* decode */
  155. errn = exiDecodeStartDocument(&iStream,
  156. &stateDecode);
  157. if (errn < 0) {
  158. #if EXI_DEBUG == EXI_DEBUG_ON
  159. printf("[Decode-ERROR-SD] %d \n", errn);
  160. #endif /*EXI_DEBUG*/
  161. return errn;
  162. }
  163. #if EXI_DEBUG == EXI_DEBUG_ON
  164. printf(">> START_DOCUMENT \n");
  165. #endif /*EXI_DEBUG*/
  166. /* encode */
  167. errn = exiEncodeStartDocument(&oStream,
  168. &stateEncode);
  169. break;
  170. case EXI_EVENT_END_DOCUMENT:
  171. /* decode */
  172. errn = exiDecodeEndDocument(&iStream,
  173. &stateDecode);
  174. if (errn < 0) {
  175. #if EXI_DEBUG == EXI_DEBUG_ON
  176. printf("[Decode-ERROR-ED] %d \n", errn);
  177. #endif /*EXI_DEBUG*/
  178. return errn;
  179. }
  180. #if EXI_DEBUG == EXI_DEBUG_ON
  181. printf(">> END_DOCUMENT \n");
  182. #endif /*EXI_DEBUG*/
  183. /* encode */
  184. errn = exiEncodeEndDocument(&oStream,
  185. &stateEncode);
  186. /* signalize end of document */
  187. noEndOfDocument = 0; /* false */
  188. break;
  189. case EXI_EVENT_START_ELEMENT:
  190. /* decode */
  191. errn = exiDecodeStartElement(&iStream,
  192. &stateDecode, &eqn);
  193. if (errn < 0) {
  194. #if EXI_DEBUG == EXI_DEBUG_ON
  195. printf("[Decode-ERROR-SE] %d \n", errn);
  196. #endif /*EXI_DEBUG*/
  197. return errn;
  198. }
  199. #if EXI_DEBUG == EXI_DEBUG_ON
  200. exiGetLocalName(&(stateDecode.nameTablePrepopulated),
  201. &(stateDecode.nameTableRuntime), eqn.namespaceURI,
  202. eqn.localPart, &localName);
  203. exiGetUri(&(stateDecode.nameTablePrepopulated),
  204. &(stateDecode.nameTableRuntime), eqn.namespaceURI,
  205. &namespaceURI);
  206. printf(">> SE_{%s}%s \n", namespaceURI,
  207. localName);
  208. #endif /*EXI_DEBUG*/
  209. /* encode */
  210. errn = exiEncodeStartElement(&oStream,
  211. &stateEncode, &eqn);
  212. break;
  213. case EXI_EVENT_START_ELEMENT_GENERIC:
  214. /* decode */
  215. errn = exiDecodeStartElementGeneric(&iStream,
  216. &stateDecode, &qn);
  217. if (errn < 0) {
  218. #if EXI_DEBUG == EXI_DEBUG_ON
  219. printf("[Decode-ERROR-SEgen] %d \n", errn);
  220. #endif /*EXI_DEBUG*/
  221. return errn;
  222. }
  223. #if EXI_DEBUG == EXI_DEBUG_ON
  224. printf(">> SE_Gen {%s}%s \n", stringNamespaceURI.chars,
  225. stringLocalName.chars);
  226. #endif /*EXI_DEBUG*/
  227. /* encode */
  228. errn = exiEncodeStartElementGeneric(&oStream,
  229. &stateEncode, &stringNamespaceURI, &stringLocalName);
  230. break;
  231. case EXI_EVENT_END_ELEMENT:
  232. /* decode */
  233. errn = exiDecodeEndElement(&iStream,
  234. &stateDecode, &eqn);
  235. if (errn < 0) {
  236. #if EXI_DEBUG == EXI_DEBUG_ON
  237. printf("[Decode-ERROR-EE] %d \n", errn);
  238. #endif /*EXI_DEBUG*/
  239. return errn;
  240. }
  241. #if EXI_DEBUG == EXI_DEBUG_ON
  242. printf("<< EE \n");
  243. #endif /*EXI_DEBUG*/
  244. /* encode */
  245. errn
  246. = exiEncodeEndElement(&oStream,
  247. &stateEncode);
  248. break;
  249. case EXI_EVENT_END_ELEMENT_UNDECLARED:
  250. /* decode */
  251. errn = exiDecodeEndElementUndeclared(&iStream,
  252. &stateDecode, &eqn);
  253. if (errn < 0) {
  254. #if EXI_DEBUG == EXI_DEBUG_ON
  255. printf("[Decode-ERROR-EE-Undecl] %d \n", errn);
  256. #endif /*EXI_DEBUG*/
  257. return errn;
  258. }
  259. #if EXI_DEBUG == EXI_DEBUG_ON
  260. printf("<< EEundecl \n");
  261. #endif /*EXI_DEBUG*/
  262. /* encode */
  263. errn
  264. = exiEncodeEndElement(&oStream,
  265. &stateEncode);
  266. break;
  267. case EXI_EVENT_CHARACTERS:
  268. /* decode */
  269. errn = exiDecodeCharacters(&iStream,
  270. &stateDecode, &val);
  271. if (errn < 0) {
  272. #if EXI_DEBUG == EXI_DEBUG_ON
  273. printf("[Decode-ERROR-CH] %d \n", errn);
  274. #endif /*EXI_DEBUG*/
  275. return errn;
  276. }
  277. #if EXI_DEBUG == EXI_DEBUG_ON
  278. debugValue(&val);
  279. #endif /*EXI_DEBUG*/
  280. /* encode */
  281. errn = exiEncodeCharacters(&oStream,
  282. &stateEncode, &val);
  283. /* list value: special behavior */
  284. if (val.type == EXI_DATATYPE_LIST) {
  285. for(k=0; k<val.list.len; k++) {
  286. errn = exiDecodeListValue(&iStream, &val, val.list);
  287. if (errn < 0) {
  288. #if EXI_DEBUG == EXI_DEBUG_ON
  289. printf("[Decode-ERROR-CH_LIST] %d \n", errn);
  290. #endif /*EXI_DEBUG*/
  291. return errn;
  292. }
  293. #if EXI_DEBUG == EXI_DEBUG_ON
  294. debugValue(&val);
  295. #endif /*EXI_DEBUG*/
  296. /* encode list value */
  297. errn = exiEncodeListValue(&oStream,
  298. &val, val.list);
  299. }
  300. }
  301. break;
  302. case EXI_EVENT_CHARACTERS_GENERIC:
  303. /* decode */
  304. errn = exiDecodeCharactersGeneric(&iStream,
  305. &stateDecode, &val);
  306. if (errn < 0) {
  307. #if EXI_DEBUG == EXI_DEBUG_ON
  308. printf("[Decode-ERROR-CHgen] %d \n", errn);
  309. #endif /*EXI_DEBUG*/
  310. return errn;
  311. }
  312. #if EXI_DEBUG == EXI_DEBUG_ON
  313. debugValue(&val);
  314. #endif /*EXI_DEBUG*/
  315. /* encode */
  316. errn = exiEncodeCharacters(&oStream,
  317. &stateEncode, &val);
  318. break;
  319. case EXI_EVENT_CHARACTERS_GENERIC_UNDECLARED:
  320. /* decode */
  321. errn = exiDecodeCharactersGenericUndeclared(
  322. &iStream, &stateDecode, &val);
  323. if (errn < 0) {
  324. #if EXI_DEBUG == EXI_DEBUG_ON
  325. printf("[Decode-ERROR-CHgenUndecl] %d \n", errn);
  326. #endif /*EXI_DEBUG*/
  327. return errn;
  328. }
  329. #if EXI_DEBUG == EXI_DEBUG_ON
  330. debugValue(&val);
  331. #endif /*EXI_DEBUG*/
  332. /* encode */
  333. errn = exiEncodeCharacters(&oStream,
  334. &stateEncode, &val);
  335. break;
  336. case EXI_EVENT_ATTRIBUTE:
  337. /* decode */
  338. errn = exiDecodeAttribute(&iStream, &stateDecode,
  339. &eqn, &val);
  340. if (errn < 0) {
  341. #if EXI_DEBUG == EXI_DEBUG_ON
  342. printf("[Decode-ERROR-AT] %d \n", errn);
  343. #endif /*EXI_DEBUG*/
  344. return errn;
  345. }
  346. #if EXI_DEBUG == EXI_DEBUG_ON
  347. exiGetLocalName(&(stateDecode.nameTablePrepopulated),
  348. &(stateDecode.nameTableRuntime), eqn.namespaceURI,
  349. eqn.localPart, &localName);
  350. exiGetUri(&(stateDecode.nameTablePrepopulated),
  351. &(stateDecode.nameTableRuntime), eqn.namespaceURI,
  352. &namespaceURI);
  353. printf(" AT {%s}%s \n", namespaceURI, localName);
  354. debugValue(&val);
  355. #endif /*EXI_DEBUG*/
  356. /* encode */
  357. errn = exiEncodeAttribute(&oStream, &stateEncode,
  358. &eqn, &val);
  359. break;
  360. case EXI_EVENT_ATTRIBUTE_XSI_NIL:
  361. /* decode */
  362. errn = exiDecodeAttributeXsiNil(&iStream,
  363. &stateDecode, &val);
  364. if (errn < 0) {
  365. #if EXI_DEBUG == EXI_DEBUG_ON
  366. printf("[Decode-ERROR-AT-NIL] %d \n", errn);
  367. #endif /*EXI_DEBUG*/
  368. return errn;
  369. }
  370. #if EXI_DEBUG == EXI_DEBUG_ON
  371. printf(" AT {xsi}nil == %i \n", val.boolean);
  372. #endif /*EXI_DEBUG*/
  373. /* encode */
  374. errn = exiEncodeAttributeXsiNil(&oStream,
  375. &stateEncode, &val);
  376. break;
  377. case EXI_EVENT_ATTRIBUTE_XSI_TYPE:
  378. /* decode */
  379. errn = exiDecodeAttributeXsiType(&iStream,
  380. &stateDecode, &val);
  381. if (errn < 0) {
  382. #if EXI_DEBUG == EXI_DEBUG_ON
  383. printf("[Decode-ERROR-AT-TYPE] %d \n", errn);
  384. #endif /*EXI_DEBUG*/
  385. return errn;
  386. }
  387. #if EXI_DEBUG == EXI_DEBUG_ON
  388. exiGetLocalName(&(stateDecode.nameTablePrepopulated),
  389. &(stateDecode.nameTableRuntime), val.eqname.namespaceURI,
  390. val.eqname.localPart, &localName);
  391. exiGetUri(&(stateDecode.nameTablePrepopulated),
  392. &(stateDecode.nameTableRuntime), val.eqname.namespaceURI,
  393. &namespaceURI);
  394. printf(" AT {type}type == {%s}%s \n", namespaceURI, localName);
  395. #endif /*EXI_DEBUG*/
  396. /* encode */
  397. errn = exiEncodeAttributeXsiType(&oStream,
  398. &stateEncode, &val);
  399. break;
  400. case EXI_EVENT_ATTRIBUTE_GENERIC_UNDECLARED:
  401. /* decode */
  402. errn = exiDecodeAttributeGenericUndeclared(
  403. &iStream, &stateDecode, &qn, &val);
  404. if (errn < 0) {
  405. #if EXI_DEBUG == EXI_DEBUG_ON
  406. printf("[Decode-ERROR-ATgenUnd] %d \n", errn);
  407. #endif /*EXI_DEBUG*/
  408. return errn;
  409. }
  410. #if EXI_DEBUG == EXI_DEBUG_ON
  411. /* exiGetLocalName(&(stateDecode.nameTablePrepopulated), &(stateDecode.nameTableRuntime), eqn.namespaceURI, eqn.localPart, &localName);
  412. exiGetUri(&(stateDecode.nameTablePrepopulated), &(stateDecode.nameTableRuntime), eqn.namespaceURI, &namespaceURI); */
  413. printf(" AT {%s}%s \n", qn.namespaceURI.chars, qn.localName.chars);
  414. debugValue(&val);
  415. #endif /*EXI_DEBUG*/
  416. /* encode */
  417. errn = exiEncodeAttribute(&oStream, &stateEncode,
  418. &eqn, &val);
  419. break;
  420. default:
  421. /* ERROR */
  422. #if EXI_DEBUG == EXI_DEBUG_ON
  423. printf("[Unknown-Event] %d \n", event);
  424. #endif /*EXI_DEBUG*/
  425. return EXI_ERROR_UNKOWN_EVENT;
  426. }
  427. } while (noEndOfDocument);
  428. #if EXI_STREAM == BYTE_ARRAY
  429. /* write to file */
  430. writeBytesToFile(oStream.data, posEncode, argv[2]);
  431. #endif
  432. #if EXI_STREAM == FILE_STREAM
  433. fclose(iStream.file);
  434. fclose(oStream.file);
  435. #endif
  436. return 0;
  437. }
  438. #if EXI_DEBUG == EXI_DEBUG_ON
  439. static void debugValue(exi_value_t* val) {
  440. int i;
  441. switch (val->type) {
  442. case EXI_DATATYPE_INTEGER:
  443. switch (val->integer.type) {
  444. /* Unsigned Integer */
  445. case EXI_UNSIGNED_INTEGER_8:
  446. printf(" Value uint8 : %d \n", val->integer.val.uint8);
  447. break;
  448. case EXI_UNSIGNED_INTEGER_16:
  449. printf(" Value uint16 : %d \n", val->integer.val.uint16);
  450. break;
  451. case EXI_UNSIGNED_INTEGER_32:
  452. printf(" Value uint32 : %d \n", val->integer.val.uint32);
  453. break;
  454. case EXI_UNSIGNED_INTEGER_64:
  455. printf(" Value uint64 : %ld \n",
  456. (long unsigned int) val->integer.val.uint64);
  457. break;
  458. /* (Signed) Integer */
  459. case EXI_INTEGER_8:
  460. printf(" Value int8 : %d \n", val->integer.val.int8);
  461. break;
  462. case EXI_INTEGER_16:
  463. printf(" Value int16 : %d \n", val->integer.val.int16);
  464. break;
  465. case EXI_INTEGER_32:
  466. printf(" Value int32 : %d \n", val->integer.val.int32);
  467. break;
  468. case EXI_INTEGER_64:
  469. printf(" Value int64 : %ld \n", (long int) val->integer.val.int64);
  470. break;
  471. }
  472. break;
  473. case EXI_DATATYPE_BINARY_BASE64:
  474. case EXI_DATATYPE_BINARY_HEX:
  475. printf(" Value Binary (len == %d) : ", val->binary.len);
  476. for (i = 0; i < val->binary.len; i++) {
  477. printf(" [%d]", val->binary.data[i]);
  478. }
  479. printf("\n");
  480. break;
  481. case EXI_DATATYPE_BOOLEAN:
  482. printf(" Value Boolean : %d \n", val->boolean);
  483. break;
  484. case EXI_DATATYPE_STRING:
  485. printf(" Value String (len==%d) : '", val->string.len);
  486. for (i = 0; i < val->string.len; i++) {
  487. printf("%c", (char) val->string.codepoints[i]);
  488. }
  489. printf("'\n");
  490. break;
  491. case EXI_DATATYPE_LIST:
  492. printf(" Value List (len==%d) \n", val->list.len);
  493. break;
  494. default:
  495. printf(" Value ?? \n");
  496. }
  497. }
  498. #endif /*EXI_DEBUG*/