libsyncml 0.5.4

- Main Page
- Modules
- Data Structures
- Files

- File List

sml_parse.c
1 /*
2 * libsyncml - A syncml protocol implementation
3 * Copyright (C) 2005 Armin Bauer <armin.bauer@opensync.org>
4 * Copyright (C) 2008 Michael Bell <michael.bell@opensync.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 #include "syncml.h"
23
24 #include "syncml_internals.h"
25 #include "sml_error_internals.h"
26 #include "sml_parse_internals.h"
27 #include "sml_command_internals.h"
28 #include "sml_elements_internals.h"
29 #include "sml_notification_internals.h"
30
31 #include "parser/sml_xml_assm.h"
32 #include "parser/sml_xml_parse.h"
33 #include "parser/sml_wbxml.h"
34
42
50 SmlParser *smlParserNew(SmlMimeType type, unsigned int limit, SmlError **error)
51 {
52 smlTrace(TRACE_ENTRY, "%s(%i, %i, %p)", __func__, type, limit, error);
53 CHECK_ERROR_REF
54
55 SmlParser *parser = smlTryMalloc0(sizeof(SmlParser), error);
56 if (!parser)
57 goto error;
58
59 parser->type = type;
60 parser->limit = limit;
61
62 switch (type) {
63 case SML_MIMETYPE_XML:
64 if (!(parser->parser_userdata = smlXmlParserNew(&(parser->functions), error)))
65 goto error_free_parser;
66 break;
67 case SML_MIMETYPE_SAN:
68 /* SANs will be converted to normal SyncML 1.1 notifications */
69 if (!(parser->parser_userdata = smlXmlParserNew(&(parser->functions), error)))
70 goto error_free_parser;
71 break;
72 case SML_MIMETYPE_WBXML:
73 #ifdef ENABLE_WBXML
74 if (!(parser->parser_userdata = smlWbxmlParserNew(&(parser->functions), error)))
75 goto error_free_parser;
76 break;
77 #else
78 smlErrorSet(error, SML_ERROR_GENERIC, "Wbxml not enabled in this build");
79 goto error_free_parser;
80 #endif
81 default:
82 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown parser type");
83 goto error_free_parser;
84 }
85
86 smlTrace(TRACE_EXIT, "%s: %p", __func__, parser);
87 return parser;
88
89 error_free_parser:
90 smlSafeFree((gpointer *)&parser);
91 error:
92 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
93 return NULL;
94 }
95
96 void smlParserSetManager(SmlParser *parser, SmlManager *manager)
97 {
98 smlAssert(parser);
99 smlAssert(manager);
100 parser->manager = manager;
101 }
102
108 void smlParserFree(SmlParser *parser)
109 {
110 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, parser);
111 smlAssert(parser);
112
113 if (parser->functions.free)
114 parser->functions.free(parser->parser_userdata);
115
116 smlSafeFree((gpointer *)&parser);
117
118 smlTrace(TRACE_EXIT, "%s", __func__);
119 }
120
132 SmlBool smlParserStart(SmlParser *parser, const char *data, unsigned int size, SmlError **error)
133 {
134 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, parser, data, size, error);
135 CHECK_ERROR_REF
136 smlAssert(parser);
137 smlAssert(data);
138 smlAssert(size);
139 smlAssert(parser->functions.start);
140 smlAssertMsg(parser->type != SML_MIMETYPE_SAN || parser->manager,
141 SML_ASSERT_MSG_SAN_PARSE_REQUIRES_MANAGER);
142
143 if (parser->limit && size > parser->limit) {
144 smlErrorSet(error, SML_ERROR_GENERIC, "Input data too large");
145 goto error;
146 }
147
148 if (parser->type == SML_MIMETYPE_SAN) {
149 /* convert OMA DS 1.2 SAN into an SyncML 1.1 notification */
150 smlTrace(TRACE_INTERNAL, "%s - detected an OMA DS 1.2 SAN", __func__);
151
152 /* parse the SAN */
153 SmlNotification *san = smlNotificationParse(data, size, error);
154 if (!san)
155 goto error;
156
157 /* fix 1.2 SAN for use with SyncML 1.1 */
158 smlNotificationSetManager(san, parser->manager);
159 san->type = SML_MIMETYPE_XML;
160 san->sessionType = SML_SESSION_TYPE_CLIENT;
161 san->target = smlLocationNew("/", NULL, error);
162 if (!san->target)
163 goto error;
164
165 /* assemble a SyncML 1.1 notification */
166 char *xmlData = NULL;
167 unsigned int xmlSize = 0;
168 if (!smlNotificationAssemble11(san, &xmlData, &xmlSize, SML_VERSION_12, error))
169 {
170 smlNotificationFree(san);
171 goto error;
172 }
173 smlTrace(TRACE_INTERNAL,
174 "%s - converted OMA DS 1.2 SAN to SyncML 1.1 server alerted sync - %s",
175 __func__, VA_STRING(xmlData));
176
177 /* cleanup notification */
178 smlNotificationFree(san);
179 san = NULL;
180
181 /* run the parser on the converted SAN */
182 if (!parser->functions.start(parser->parser_userdata, xmlData, xmlSize, error)) {
183 smlSafeCFree(&xmlData);
184 goto error;
185 }
186 smlSafeCFree(&xmlData);
187 } else {
188 /* run the parser directly on the data */
189 if (!parser->functions.start(parser->parser_userdata, data, size, error))
190 goto error;
191 }
192
193 smlTrace(TRACE_EXIT, "%s", __func__);
194 return TRUE;
195
196 error:
197 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
198 return FALSE;
199 }
200
216 SmlBool smlParserGetHeader(SmlParser *parser, SmlHeader **header, SmlCred **cred, SmlError **error)
217 {
218 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, header, cred, error);
219 CHECK_ERROR_REF
220 smlAssert(parser);
221 smlAssert(header);
222 smlAssert(cred);
223 smlAssert(parser->functions.get_header);
224
225 if (!parser->functions.get_header(parser->parser_userdata, header, cred, error))
226 goto error;
227
228 smlTrace(TRACE_EXIT, "%s", __func__);
229 return TRUE;
230
231 error:
232 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
233 return FALSE;
234 }
235
250 SmlParserResult smlParserGetCommand(SmlParser *parser, SmlCommand **cmd, SmlError **error)
251 {
252 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, cmd, error);
253 CHECK_ERROR_REF
254 smlAssert(parser);
255 smlAssert(cmd);
256 smlAssert(parser->functions.get_cmd);
257 SmlParserResult result = SML_PARSER_RESULT_ERROR;
258
259 if (!(result = parser->functions.get_cmd(parser->parser_userdata, cmd, error)))
260 goto error;
261
262 smlTrace(TRACE_EXIT, "%s: %i", __func__, result);
263 return result;
264
265 error:
266 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
267 return SML_PARSER_RESULT_ERROR;
268 }
269
284 SmlBool smlParserGetStatus(SmlParser *parser, SmlStatus **status, SmlError **error)
285 {
286 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, parser, status, error);
287 CHECK_ERROR_REF
288 smlAssert(parser);
289 smlAssert(status);
290 smlAssert(parser->functions.get_status);
291
292 if (!parser->functions.get_status(parser->parser_userdata, status, error))
293 goto error;
294
295 smlTrace(TRACE_EXIT, "%s", __func__);
296 return TRUE;
297
298 error:
299 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
300 return FALSE;
301 }
302
314 SmlBool smlParserEnd(SmlParser *parser, SmlBool *final, SmlBool *end, SmlError **error)
315 {
316 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, parser, final, end, error);
317 CHECK_ERROR_REF
318 smlAssert(parser);
319 smlAssert(parser->functions.end);
320
321 if (!parser->functions.end(parser->parser_userdata, final, end, error))
322 goto error;
323
324 smlTrace(TRACE_INTERNAL, "%s: Final %i, End %i", __func__, final ? *final : -1, end ? *end : -1);
325
326 smlTrace(TRACE_EXIT, "%s", __func__);
327 return TRUE;
328
329 error:
330 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
331 return FALSE;
332 }
333
343
352 SmlAssembler *smlAssemblerNew(SmlMimeType type, unsigned int limit, SmlError **error)
353 {
354 smlTrace(TRACE_ENTRY, "%s(%i, %i, %p)", __func__, type, limit, error);
355 CHECK_ERROR_REF
356
357 SmlAssembler *assm = smlTryMalloc0(sizeof(SmlAssembler), error);
358 if (!assm)
359 goto error;
360
361 assm->type = type;
362 assm->remoteMaxMsgSize = limit;
363 assm->empty = TRUE;
364 assm->remoteMaxObjSize = 0;
365
366 switch (type) {
367 case SML_MIMETYPE_XML:
368 if (!(assm->assm_userdata = smlXmlAssemblerNew(assm, &(assm->functions), error)))
369 goto error_free_assm;
370 break;
371 case SML_MIMETYPE_WBXML:
372 #ifdef ENABLE_WBXML
373 if (!(assm->assm_userdata = smlWbxmlAssemblerNew(assm, &(assm->functions), error)))
374 goto error_free_assm;
375 break;
376 #else
377 smlErrorSet(error, SML_ERROR_GENERIC, "Wbxml not enabled in this build");
378 goto error_free_assm;
379 #endif
380 default:
381 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown assembler type");
382 goto error_free_assm;
383 }
384
385 assm->options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
386
387 smlTrace(TRACE_EXIT, "%s: %p", __func__, assm);
388 return assm;
389
390 error_free_assm:
391 smlSafeFree((gpointer *)&assm);
392 error:
393 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
394 return NULL;
395 }
396
402 void smlAssemblerFree(SmlAssembler *assm)
403 {
404 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
405 smlAssert(assm);
406
407 if (assm->functions.free)
408 assm->functions.free(assm->assm_userdata);
409
410 g_hash_table_destroy(assm->options);
411
412 smlSafeFree((gpointer *)&assm);
413
414 smlTrace(TRACE_EXIT, "%s", __func__);
415 }
416
428 SmlBool smlAssemblerStart(SmlAssembler *assm, SmlSession *session, SmlError **error)
429 {
430 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assm, session, error);
431 CHECK_ERROR_REF
432 smlAssert(assm);
433 smlAssert(session);
434 smlAssert(assm->functions.start);
435
436 if (!assm->functions.start(assm->assm_userdata, session, error))
437 goto error;
438
439 smlTrace(TRACE_EXIT, "%s", __func__);
440 return TRUE;
441
442 error:
443 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
444 return FALSE;
445 }
446
456 SmlBool smlAssemblerRun(SmlAssembler *assm, char **data, unsigned int *size, SmlBool *end, SmlBool final, SmlError **error)
457 {
458 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %i, %p)", __func__, assm, data, size, end, final, error);
459 CHECK_ERROR_REF
460 smlAssert(assm);
461 smlAssert(data);
462 smlAssert(size);
463 smlAssert(assm->functions.run);
464
465 if (!assm->functions.run(assm->assm_userdata, data, size, end, final, smlAssemblerGetRemoteMaxMsgSize(assm), error))
466 goto error;
467
468 smlTrace(TRACE_EXIT, "%s", __func__);
469 return TRUE;
470
471 error:
472 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
473 return FALSE;
474 }
475
485 unsigned int smlAssemblerCheckSize(SmlAssembler *assm, SmlBool headeronly, SmlError **error)
486 {
487 smlTrace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, assm, headeronly, error);
488 CHECK_ERROR_REF
489 smlAssert(assm);
490 smlAssert(assm->functions.check_size);
491
492 unsigned int size = 0;
493 if (!(size = assm->functions.check_size(assm->assm_userdata, headeronly, error)))
494 goto error;
495
496 smlTrace(TRACE_EXIT, "%s: %i", __func__, size);
497 return size;
498
499 error:
500 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
501 return 0;
502 }
503
514 unsigned int smlAssemblerFlush(SmlAssembler *assm)
515 {
516 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
517 smlAssert(assm);
518 smlAssert(assm->functions.flush);
519
520 unsigned int ret = assm->functions.flush(assm->assm_userdata);
521 assm->empty = TRUE;
522
523 smlTrace(TRACE_EXIT, "%s: %i", __func__, ret);
524 return ret;
525 }
526
527 void smlAssemblerRestoreCommands(SmlAssembler *assm)
528 {
529 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
530 smlAssert(assm);
531 smlAssert(assm->functions.restore_cmds);
532
533 assm->functions.restore_cmds(assm->assm_userdata);
534 assm->empty = FALSE;
535
536 smlTrace(TRACE_EXIT, "%s", __func__);
537 }
538
545 SmlBool smlAssemblerGetSpace(SmlAssembler *assm, int *space, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
546 {
547 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p, %p)", __func__, assm, space, parent, cmd, error);
548 CHECK_ERROR_REF
549 smlAssert(assm);
550 smlAssert(space);
551 smlAssert(cmd);
552 smlAssert(assm->functions.start_cmd);
553 smlAssert(assm->functions.rem_cmd);
554 smlAssert(cmd->type == SML_COMMAND_TYPE_ADD || cmd->type == SML_COMMAND_TYPE_REPLACE);
555 unsigned int parentID = 0;
556
557 int limit = smlAssemblerGetRemoteMaxMsgSize(assm);
558 if (!limit) {
559 *space = -1;
560 smlTrace(TRACE_EXIT, "%s: No limit", __func__);
561 return TRUE;
562 }
563
564 /* Add the command */
565 if (parent) {
566 if (!parent->cmdID) {
567 smlErrorSet(error, SML_ERROR_GENERIC, "Parent has to be added before");
568 goto error;
569 }
570 parentID = parent->cmdID;
571 }
572
573 /* disable the items */
574 if (cmd->private.change.items)
575 {
576 guint i;
577 for (i=0; i < g_list_length(cmd->private.change.items); i++)
578 {
579 SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
580 item->disabled = TRUE;
581 }
582 }
583
584 SmlBool noCmdID = FALSE;
585 if (!cmd->cmdID) {
586 noCmdID = TRUE;
587 /* FIXME: This code does not support more
588 * FIXME: than 99.999 commands in one session. */
589 cmd->cmdID = 10000;
590 }
591
592 if (!assm->functions.start_cmd(assm->assm_userdata, parentID, cmd, error))
593 goto error_enable_item;
594
595 /* Now check the size */
596 int size = 0;
597 if (!(size = smlAssemblerCheckSize(assm, FALSE, error)))
598 goto error_remove;
599
600 if (limit <= size)
601 *space = 0;
602 else
603 *space = limit - size - 10;
604
605 /* Remove the command again */
606 if (!assm->functions.rem_cmd(assm->assm_userdata, parentID, error))
607 goto error_remove;
608
609 /* enable the items again */
610 if (cmd->private.change.items)
611 {
612 guint i;
613 for (i=0; i < g_list_length(cmd->private.change.items); i++)
614 {
615 SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
616 item->disabled = FALSE;
617 }
618 }
619
620 if (noCmdID)
621 cmd->cmdID = 0;
622
623 smlTrace(TRACE_EXIT, "%s: %i", __func__, *space);
624 return TRUE;
625
626 error_remove:
627 assm->functions.rem_cmd(assm->assm_userdata, parentID, NULL);
628 error_enable_item:
629 if (cmd->private.change.items)
630 {
631 guint i;
632 for (i=0; i < g_list_length(cmd->private.change.items); i++)
633 {
634 SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
635 item->disabled = FALSE;
636 }
637 }
638 if (noCmdID)
639 cmd->cmdID = 0;
640 error:
641 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
642 return FALSE;
643 }
644
659 SmlAssemblerResult smlAssemblerStartCommand(SmlAssembler *assm, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
660 {
661 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, assm, parent, cmd, error);
662 CHECK_ERROR_REF
663 smlAssert(assm);
664 smlAssert(cmd);
665 smlAssert(assm->functions.start_cmd);
666 smlAssert(assm->functions.rem_cmd);
667 unsigned int parentID = 0;
668
669 /* Add the command */
670 if (parent) {
671 if (!parent->cmdID) {
672 smlErrorSet(error, SML_ERROR_GENERIC, "Parent has to be added before");
673 goto error;
674 }
675 parentID = parent->cmdID;
676 }
677
678 if (!assm->functions.start_cmd(assm->assm_userdata, parentID, cmd, error))
679 goto error;
680
681 /* Lets see if the new buffer is small enough */
682 int limit = smlAssemblerGetRemoteMaxMsgSize(assm);
683 if (limit) {
684 /* Now check the size */
685 int size = 0;
686 if (!(size = smlAssemblerCheckSize(assm, FALSE, error)))
687 goto error;
688
689 if (size > limit) {
690 /* The status does not fit. Remove it again */
691 if (!assm->functions.rem_cmd(assm->assm_userdata, parentID, error))
692 goto error;
693
694 smlTrace(TRACE_EXIT, "%s: Mismatch", __func__);
695 return SML_ASSEMBLER_RESULT_MISMATCH;
696 }
697 smlTrace(TRACE_INTERNAL, "%s: size %i, limit %i", __func__, size, limit);
698 }
699
700 if (cmd->cmdID)
701 assm->empty = FALSE;
702
703 smlTrace(TRACE_EXIT, "%s", __func__);
704 return SML_ASSEMBLER_RESULT_OK;
705
706 error:
707 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
708 return SML_ASSEMBLER_RESULT_ERROR;
709 }
710
722 SmlBool smlAssemblerEndCommand(SmlAssembler *assm, SmlCommand *parent, SmlError **error)
723 {
724 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assm, parent, error);
725 CHECK_ERROR_REF
726 smlAssert(assm);
727 smlAssert(assm->functions.end_cmd);
728
729 unsigned int parentID = 0;
730
731 /* Add the command */
732 if (parent) {
733 if (!parent->cmdID) {
734 smlErrorSet(error, SML_ERROR_GENERIC, "Parent has to be added before");
735 goto error;
736 }
737 parentID = parent->cmdID;
738 }
739
740 /* End the command */
741 if (!assm->functions.end_cmd(assm->assm_userdata, parentID, error))
742 goto error;
743
744 smlTrace(TRACE_EXIT, "%s", __func__);
745 return TRUE;
746
747 error:
748 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
749 return FALSE;
750 }
751
762 SmlBool smlAssemblerAddHeader(SmlAssembler *assm, SmlSession *session, SmlError **error)
763 {
764 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, assm, session, error);
765 CHECK_ERROR_REF
766 smlAssert(assm);
767 smlAssert(session);
768 smlAssert(assm->functions.add_header);
769
770 /* Add the command */
771 if (!assm->functions.add_header(assm->assm_userdata, session, error))
772 goto error;
773
774 /* Now check the size */
775 unsigned int size = 0;
776 if (!(size = smlAssemblerCheckSize(assm, TRUE, error)))
777 goto error;
778
779 /* Lets see if the new buffer is small enough */
780 if (smlAssemblerGetRemoteMaxMsgSize(assm) && size > smlAssemblerGetRemoteMaxMsgSize(assm)) {
781 smlErrorSet(error, SML_ERROR_GENERIC, "Limit to small. Unable to fit a the header");
782 goto error;
783 }
784
785 smlTrace(TRACE_EXIT, "%s", __func__);
786 return TRUE;
787
788 error:
789 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
790 return FALSE;
791 }
792
806 SmlAssemblerResult smlAssemblerReserveStatus(SmlAssembler *assm, unsigned int cmdRef, unsigned int msgRef, unsigned int cmdID, SmlError **error)
807 {
808 smlTrace(TRACE_ENTRY, "%s(%p, %i, %i, %i, %p)", __func__, assm, cmdRef, msgRef, cmdID, error);
809 CHECK_ERROR_REF
810 smlAssert(assm);
811 smlAssert(assm->functions.reserve_status);
812
813 /* Reserve the status */
814 if (!assm->functions.reserve_status(assm->assm_userdata, cmdRef, msgRef, cmdID, error))
815 goto error;
816
817 smlTrace(TRACE_EXIT, "%s", __func__);
818 return TRUE;
819
820 error:
821 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
822 return FALSE;
823 }
824
839 SmlAssemblerResult smlAssemblerAddStatusFull(SmlAssembler *assm, SmlStatus *status, SmlBool force, SmlError **error)
840 {
841 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, assm, status, force, error);
842 CHECK_ERROR_REF
843 smlAssert(assm);
844 smlAssert(status);
845 smlAssert(assm->functions.add_status);
846 smlAssert(assm->functions.rem_status);
847
848 /* Add the status */
849 if (!assm->functions.add_status(assm->assm_userdata, status, error))
850 goto error;
851
852 if (!force) {
853 /* Lets see if the new buffer is small enough */
854 int limit = smlAssemblerGetRemoteMaxMsgSize(assm);
855 if (limit) {
856 /* Now check the size */
857 int size = 0;
858 if (!(size = smlAssemblerCheckSize(assm, FALSE, error)))
859 goto error;
860
861 if (size > limit) {
862 /* The status does not fit. Remove it again */
863 if (!assm->functions.rem_status(assm->assm_userdata, error))
864 goto error;
865
866 smlTrace(TRACE_EXIT, "%s: Mismatch", __func__);
867 return SML_ASSEMBLER_RESULT_MISMATCH;
868 }
869 }
870 }
871
872 /*if (status->cmdRef != 0)
873 assm->empty = FALSE;*/
874
875 smlTrace(TRACE_EXIT, "%s", __func__);
876 return SML_ASSEMBLER_RESULT_OK;
877
878 error:
879 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
880 return SML_ASSEMBLER_RESULT_ERROR;
881 }
882
883 SmlAssemblerResult smlAssemblerAddStatus(SmlAssembler *assm, SmlStatus *status, SmlError **error)
884 {
885 CHECK_ERROR_REF
886 return smlAssemblerAddStatusFull(assm, status, FALSE, error);
887 }
888
896 void smlAssemblerSetOption(SmlAssembler *assm, const char *optionname, const char *value)
897 {
898 smlTrace(TRACE_ENTRY, "%s(%p, %s, %s)", __func__, assm, VA_STRING(optionname), VA_STRING(value));
899 smlAssert(assm);
900 smlAssert(optionname);
901
902 g_hash_table_replace(assm->options, g_strdup(optionname), g_strdup(value));
903
904 smlTrace(TRACE_EXIT, "%s", __func__);
905 }
906
914 const char *smlAssemblerGetOption(SmlAssembler *assm, const char *optionname)
915 {
916 smlTrace(TRACE_ENTRY, "%s(%p, %s)", __func__, assm, VA_STRING(optionname));
917 smlAssert(assm);
918 smlAssert(optionname);
919
920 const char *ret = g_hash_table_lookup(assm->options, optionname);
921
922 smlTrace(TRACE_EXIT, "%s: %s", __func__, VA_STRING(ret));
923 return ret;
924 }
925
926 /* FIXME: DEPRECATED */
927 unsigned int smlAssemblerGetLimit(SmlAssembler *assm)
928 {
929 return smlAssemblerGetRemoteMaxMsgSize(assm);
930 }
931
932 unsigned int smlAssemblerGetRemoteMaxMsgSize(SmlAssembler *assm)
933 {
934 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
935 smlAssert(assm);
936
937 smlTrace(TRACE_EXIT, "%s: %i", __func__, assm->remoteMaxMsgSize);
938 return assm->remoteMaxMsgSize;
939 }
940
941 /* FIXME: DEPRECATED */
942 void smlAssemblerSetRequestedLimit(SmlAssembler *assm, unsigned int limit)
943 {
944 smlAssemblerSetRemoteMaxMsgSize(assm, limit);
945 }
946
947 /* FIXME: DEPRECATED */
948 void smlAssemblerSetLimit(SmlAssembler *assm, unsigned int limit)
949 {
950 smlAssemblerSetRemoteMaxMsgSize(assm, limit);
951 }
952
953 unsigned int smlAssemblerSetRemoteMaxMsgSize(SmlAssembler *assm, unsigned int limit)
954 {
955 smlTrace(TRACE_ENTRY, "%s(%p, %i)", __func__, assm, limit);
956 smlAssert(assm);
957
958 if (limit == 0)
959 {
960 /* Reset MaxMsgSize to unused state */
961 assm->remoteMaxMsgSize = limit;
962 } else {
963 if (limit < assm->remoteMaxMsgSize || assm->remoteMaxMsgSize == 0)
964 {
965 /* There is a real new limit. */
966 assm->remoteMaxMsgSize = limit;
967 } else {
968 smlTrace(TRACE_INTERNAL,
969 "%s: using old limit (%d) because of large new limit (%d).",
970 __func__, assm->remoteMaxMsgSize, limit);
971 }
972 }
973
974 smlTrace(TRACE_EXIT, "%s - %d", __func__, assm->remoteMaxMsgSize);
975 return assm->remoteMaxMsgSize;
976 }
977
978 /* FIXME: DEPRECATED */
979 int smlAssemblerGetSendingMaxObjSize(SmlAssembler *assm)
980 {
981 return smlAssemblerGetRemoteMaxObjSize(assm);
982 }
983
984 /* FIXME: DEPRECATED */
985 int smlAssemblerGetRequestedMaxObjSize(SmlAssembler *assm)
986 {
987 return smlAssemblerGetRemoteMaxObjSize(assm);
988 }
989
990
991 unsigned int smlAssemblerGetRemoteMaxObjSize(SmlAssembler *assm)
992 {
993 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
994 smlAssert(assm);
995
996 smlTrace(TRACE_EXIT, "%s: %i", __func__, assm->remoteMaxObjSize);
997 return assm->remoteMaxObjSize;
998 }
999
1000 /* FIXME: DEPRECATED */
1001 void smlAssemblerSetRequestedMaxObjSize(SmlAssembler *assm, int limit)
1002 {
1003 smlAssemblerSetRemoteMaxObjSize(assm, limit);
1004 }
1005
1006 /* FIXME: DEPRECATED */
1007 void smlAssemblerSetSendingMaxObjSize(SmlAssembler *assm, int limit)
1008 {
1009 smlAssemblerSetRemoteMaxObjSize(assm, limit);
1010 }
1011
1012 unsigned int smlAssemblerSetRemoteMaxObjSize(SmlAssembler *assm, unsigned int limit)
1013 {
1014 smlTrace(TRACE_ENTRY, "%s(%p, %i)", __func__, assm, limit);
1015 smlAssert(assm);
1016
1017 if (limit == 0)
1018 {
1019 /* Reset MaxObjSize to unused state */
1020 assm->remoteMaxObjSize = limit;
1021 } else {
1022 if (limit < assm->remoteMaxObjSize || assm->remoteMaxObjSize == 0)
1023 {
1024 /* There is a real new limit. */
1025 assm->remoteMaxObjSize = limit;
1026 } else {
1027 smlTrace(TRACE_INTERNAL,
1028 "%s: using old limit (%d) because of large new limit (%d).",
1029 __func__, assm->remoteMaxObjSize, limit);
1030 }
1031 }
1032
1033 smlTrace(TRACE_EXIT, "%s - %d", __func__, assm->remoteMaxObjSize);
1034 return assm->remoteMaxObjSize;
1035 }
1036
1037 SmlBool smlAssemblerIsEmpty(SmlAssembler *assm)
1038 {
1039 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, assm);
1040 smlAssert(assm);
1041
1042 SmlBool ret = assm->empty;
1043
1044 smlTrace(TRACE_EXIT, "%s: %i", __func__, ret);
1045 return ret;
1046 }
1047
1053 SmlBool smlAssemblerIsStatusMissing(SmlAssembler *assm)
1054 {
1055 smlAssert(assm);
1056 smlAssert(assm->functions.missing_status);
1057
1058 SmlBool ret = assm->functions.missing_status(assm->assm_userdata);
1059
1060 return ret;
1061 }
1062
1063 SmlBool smlAssemblerGetNextCmdRef(SmlAssembler *assm, unsigned int *cmdRef, unsigned int *msgRef)
1064 {
1065 smlAssert(assm);
1066 smlAssert(cmdRef);
1067 smlAssert(msgRef);
1068 smlAssert(assm->functions.next_cmdref);
1069
1070 return assm->functions.next_cmdref(assm->assm_userdata, cmdRef, msgRef);
1071 }
1072