24 #include "syncml_internals.h"
25 #include "sml_parse_internals.h"
26 #include "sml_command_internals.h"
27 #include "sml_session_internals.h"
28 #include "sml_elements_internals.h"
29 #include "sml_error_internals.h"
31 SmlCommandType smlCommandTypeFromString(
const char *name,
SmlError **error)
35 return SML_COMMAND_TYPE_UNKNOWN;
37 if (!strcmp(name, SML_ELEMENT_ALERT)) {
38 return SML_COMMAND_TYPE_ALERT;
39 }
else if (!strcmp(name, SML_ELEMENT_SYNC)) {
40 return SML_COMMAND_TYPE_SYNC;
41 }
else if (!strcmp(name, SML_ELEMENT_PUT)) {
42 return SML_COMMAND_TYPE_PUT;
43 }
else if (!strcmp(name, SML_ELEMENT_SYNCHDR)) {
44 return SML_COMMAND_TYPE_HEADER;
45 }
else if (!strcmp(name, SML_ELEMENT_ADD)) {
46 return SML_COMMAND_TYPE_ADD;
47 }
else if (!strcmp(name, SML_ELEMENT_REPLACE)) {
48 return SML_COMMAND_TYPE_REPLACE;
49 }
else if (!strcmp(name, SML_ELEMENT_MAP)) {
50 return SML_COMMAND_TYPE_MAP;
51 }
else if (!strcmp(name, SML_ELEMENT_DELETE)) {
52 return SML_COMMAND_TYPE_DELETE;
53 }
else if (!strcmp(name, SML_ELEMENT_RESULTS)) {
54 return SML_COMMAND_TYPE_RESULTS;
55 }
else if (!strcmp(name, SML_ELEMENT_GET)) {
56 return SML_COMMAND_TYPE_GET;
59 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown command name \"%s\"", name);
60 return SML_COMMAND_TYPE_UNKNOWN;
63 const char *smlCommandTypeToString(SmlCommandType type,
SmlError **error)
67 case SML_COMMAND_TYPE_ALERT:
68 return SML_ELEMENT_ALERT;
69 case SML_COMMAND_TYPE_SYNC:
70 return SML_ELEMENT_SYNC;
71 case SML_COMMAND_TYPE_PUT:
72 return SML_ELEMENT_PUT;
73 case SML_COMMAND_TYPE_HEADER:
74 return SML_ELEMENT_SYNCHDR;
75 case SML_COMMAND_TYPE_ADD:
76 return SML_ELEMENT_ADD;
77 case SML_COMMAND_TYPE_REPLACE:
78 return SML_ELEMENT_REPLACE;
79 case SML_COMMAND_TYPE_DELETE:
80 return SML_ELEMENT_DELETE;
81 case SML_COMMAND_TYPE_MAP:
82 return SML_ELEMENT_MAP;
83 case SML_COMMAND_TYPE_GET:
84 return SML_ELEMENT_GET;
85 case SML_COMMAND_TYPE_RESULTS:
86 return SML_ELEMENT_RESULTS;
91 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown command type \"%i\"", type);
97 smlTrace(TRACE_ENTRY,
"%s(%i, %i, %i, %p, %p, %i, %p)", __func__, data, cmdref, msgref, sourceref, targetref, type, error);
104 status->cmdRef = cmdref;
105 status->msgRef = msgref;
107 if (data != SML_ERROR_UNKNOWN)
108 status->data = g_strdup_printf(
"%i", data);
111 status->sourceRef = sourceref;
112 smlLocationRef(sourceref);
116 status->targetRef = targetref;
117 smlLocationRef(targetref);
120 smlTrace(TRACE_EXIT,
"%s: %p", __func__, status);
130 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, status);
133 g_atomic_int_inc(&(status->refCount));
135 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, status->refCount);
141 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, status);
144 if (g_atomic_int_dec_and_test(&(status->refCount))) {
145 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
147 if (status->sourceRef)
148 smlLocationUnref(status->sourceRef);
150 if (status->targetRef)
151 smlLocationUnref(status->targetRef);
154 smlSafeCFree(&(status->data));
157 smlAnchorFree(status->anchor);
160 smlItemUnref(status->item);
162 smlSafeFree((gpointer *)&status);
165 smlTrace(TRACE_EXIT,
"%s", __func__);
168 SmlErrorType smlStatusGetCode(
SmlStatus *status)
171 smlAssert(status->data);
172 return atoi(status->data);
175 SmlErrorClass smlStatusGetClass(
SmlStatus *status)
178 smlAssert(status->data);
179 return (atoi(status->data) / 100);
184 if (status->type == SML_COMMAND_TYPE_RESULTS)
185 return status->result;
189 SmlBool smlStatusIsResult(
SmlStatus *status)
191 return status->type == SML_COMMAND_TYPE_RESULTS ? TRUE : FALSE;
196 smlTrace(TRACE_ENTRY,
"%s(%i, %p)", __func__, type, error);
206 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
216 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, cmd, code, error);
220 SmlStatus *reply = smlStatusNew(code, cmd->cmdID, cmd->msgID, cmd->source, cmd->target, cmd->type, error);
225 case SML_COMMAND_TYPE_ALERT:
226 if (cmd->private.alert.anchor) {
227 reply->anchor = smlAnchorNew(NULL, cmd->private.alert.anchor->next, error);
236 smlTrace(TRACE_EXIT,
"%s: %p", __func__, reply);
246 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %i, %s, %p)", __func__, cmd, source, data, size, VA_STRING(contenttype), error);
250 SmlCommand *result = smlCommandNew(SML_COMMAND_TYPE_RESULTS, error);
254 result->private.results.status = smlStatusNew(SML_NO_ERROR, cmd->cmdID, cmd->msgID, cmd->source, cmd->target, SML_COMMAND_TYPE_RESULTS, error);
255 if (!result->private.results.status)
258 result->private.results.status->item = smlItemNewForData(data, size, error);
260 if (!result->private.results.status->item)
263 result->private.results.status->item->contenttype = g_strdup(contenttype);
264 result->private.results.status->item->source = smlLocationClone(source, error);
266 if (!result->private.results.status->item->source)
269 smlTrace(TRACE_EXIT,
"%s: %p", __func__, result);
273 smlCommandUnref(result);
283 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, cmd);
286 g_atomic_int_inc(&(cmd->refCount));
288 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, cmd->refCount);
294 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, cmd);
297 if (g_atomic_int_dec_and_test(&(cmd->refCount))) {
298 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
301 cmd->parent->children = g_list_remove(cmd->parent->children, cmd);
303 smlCommandUnref(cmd->parent);
308 case SML_COMMAND_TYPE_UNKNOWN:
309 case SML_COMMAND_TYPE_HEADER:
310 case SML_COMMAND_TYPE_SYNC:
312 case SML_COMMAND_TYPE_ALERT:
313 if (cmd->private.alert.anchor)
314 smlAnchorFree(cmd->private.alert.anchor);
315 if (cmd->private.alert.contentType)
316 smlSafeCFree(&(cmd->private.alert.contentType));
318 case SML_COMMAND_TYPE_PUT:
319 case SML_COMMAND_TYPE_GET:
320 if (cmd->private.access.type)
321 smlSafeCFree(&(cmd->private.access.type));
323 if (cmd->private.access.item)
324 smlItemUnref(cmd->private.access.item);
326 case SML_COMMAND_TYPE_ADD:
327 case SML_COMMAND_TYPE_REPLACE:
328 case SML_COMMAND_TYPE_DELETE:
329 if (cmd->private.change.items)
332 for (i = 0; i < g_list_length(cmd->private.change.items); i++)
334 SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
337 g_list_free(cmd->private.change.items);
340 case SML_COMMAND_TYPE_MAP:
341 while (cmd->private.map.items) {
342 SmlMapItem *item = cmd->private.map.items->data;
343 smlMapItemUnref(item);
344 cmd->private.map.items = g_list_delete_link(cmd->private.map.items, cmd->private.map.items);
347 case SML_COMMAND_TYPE_RESULTS:
348 if (cmd->private.results.status)
349 smlStatusUnref(cmd->private.results.status);
354 smlLocationUnref(cmd->target);
357 smlLocationUnref(cmd->source);
359 smlSafeFree((gpointer *)&cmd);
362 smlTrace(TRACE_EXIT,
"%s", __func__);
365 SmlCommand *smlCommandNewChange(SmlChangeType type,
const char *uid,
const char *data,
unsigned int size,
const char *contenttype,
SmlError **error)
367 smlTrace(TRACE_ENTRY,
"%s(%i, %s, %p, %i, %s, %p)", __func__, type, VA_STRING(uid), data, size, VA_STRING(contenttype), error);
373 cmd = smlCommandNew(SML_COMMAND_TYPE_ADD, error);
375 case SML_CHANGE_REPLACE:
376 cmd = smlCommandNew(SML_COMMAND_TYPE_REPLACE, error);
378 case SML_CHANGE_DELETE:
379 cmd = smlCommandNew(SML_COMMAND_TYPE_DELETE, error);
382 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown changetype");
387 SmlItem *item = smlItemNewForData(data, size, error);
390 cmd->private.change.items = g_list_append(NULL, item);
391 if (!cmd->private.change.items)
397 SmlLocation *loc = smlLocationNew(uid, NULL, error);
408 if (type != SML_CHANGE_ADD) {
416 item->contenttype = g_strdup(contenttype);
418 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
422 smlCommandUnref(cmd);
435 smlTrace(TRACE_ENTRY,
"%s(%i, %s, %p, %i, %i, %s, %p)", __func__, type, VA_STRING(uid), data, complete_size, partial_size, VA_STRING(contenttype), error);
441 cmd = smlCommandNew(SML_COMMAND_TYPE_ADD, error);
443 case SML_CHANGE_REPLACE:
444 cmd = smlCommandNew(SML_COMMAND_TYPE_REPLACE, error);
446 case SML_CHANGE_DELETE:
447 cmd = smlCommandNew(SML_COMMAND_TYPE_DELETE, error);
450 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown changetype");
454 cmd->size = complete_size;
456 SmlItem *item = smlItemNewForData(data, partial_size, error);
459 cmd->private.change.items = g_list_append(NULL, item);
460 if (!cmd->private.change.items)
466 SmlLocation *loc = smlLocationNew(uid, NULL, error);
470 if (type != SML_CHANGE_ADD)
475 item->moreData = TRUE;
476 item->contenttype = g_strdup(contenttype);
478 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
482 smlCommandUnref(cmd);
490 smlTrace(TRACE_ENTRY,
"%s(%i, %p, %p, %s, %s, %s, %p)", __func__, type, target, source, VA_STRING(next), VA_STRING(last), VA_STRING(contenttype), error);
493 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_ALERT, error);
498 cmd->target = target;
499 smlLocationRef(target);
503 cmd->source = source;
504 smlLocationRef(source);
511 if (type != SML_ALERT_NEXT_MESSAGE && type != SML_ALERT_TWO_WAY_BY_SERVER) {
518 if (type == SML_ALERT_SLOW_SYNC) {
521 "%s: removing last anchor (%s) from slow sync alert",
522 __func__, VA_STRING(last));
523 cmd->private.alert.anchor = smlAnchorNew(NULL, next, error);
525 cmd->private.alert.anchor = smlAnchorNew(last, next, error);
526 if (!cmd->private.alert.anchor)
529 cmd->private.alert.
type = type;
530 cmd->private.alert.contentType = g_strdup(contenttype);
532 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
542 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %i, %p)", __func__, target, source, num_changes, error);
544 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_SYNC, error);
548 cmd->target = target;
549 smlLocationRef(target);
551 cmd->source = source;
552 smlLocationRef(source);
554 cmd->private.sync.numChanged = num_changes;
556 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
566 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %i, %s, %p)", __func__, target, source, data, size, VA_STRING(contenttype), error);
569 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_PUT, error);
573 cmd->private.access.item = smlItemNewForData(data, size, error);
574 if (!cmd->private.access.item)
578 cmd->target = target;
579 smlLocationRef(target);
580 smlItemSetTarget(cmd->private.access.item, cmd->target);
584 cmd->source = source;
585 smlLocationRef(source);
586 smlItemSetSource(cmd->private.access.item, cmd->source);
589 cmd->private.access.item->contenttype = g_strdup(contenttype);
591 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
595 smlCommandUnref(cmd);
603 smlTrace(TRACE_ENTRY,
"%s(%p, %s, %p)", __func__, target, VA_STRING(contenttype), error);
607 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_GET, error);
611 cmd->private.access.item = smlItemNew(0, error);
612 if (!cmd->private.access.item)
615 cmd->target = target;
616 smlLocationRef(target);
617 smlItemSetTarget(cmd->private.access.item, cmd->target);
619 cmd->private.access.item->contenttype = g_strdup(contenttype);
621 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
625 smlCommandUnref(cmd);
633 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, target, source, error);
636 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_MAP, error);
640 cmd->target = target;
641 smlLocationRef(target);
643 cmd->source = source;
644 smlLocationRef(source);
646 smlTrace(TRACE_EXIT,
"%s: %p", __func__, cmd);
656 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, map, item, error);
659 smlAssert(map->type == SML_COMMAND_TYPE_MAP);
663 map->private.map.items = g_list_append(map->private.map.items, item);
665 smlTrace(TRACE_EXIT,
"%s", __func__);
669 SmlAlertType smlAlertTypeConvert(
unsigned int id,
SmlError **error)
671 smlTrace(TRACE_ENTRY,
"%s(%u, %p)", __func__,
id, error);
676 (200 <=
id &&
id <= 210) ||
677 (221 <=
id &&
id <= 223))
679 SmlAlertType result = (SmlAlertType)
id;
680 smlTrace(TRACE_EXIT,
"%s - %u", __func__, result);
684 "The unknown alert code %u was detected.",
id);
686 return SML_ALERT_UNKNOWN;
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
SmlCommand * smlCommandNewPartialChange(SmlChangeType type, const char *uid, const char *data, unsigned int complete_size, unsigned int partial_size, const char *contenttype, SmlError **error)
void * smlTryMalloc0(long n_bytes, SmlError **error)
Safely mallocs.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.