utils.c

Go to the documentation of this file.
00001 /*
00002  EasyDbus: DBUS Binding Library.
00003  Copyright (C) 2007  Daniele Rondina aka ge@@ru, geaaru@gmail.com 
00004 
00005  This program is free software; you can redistribute it and/or
00006  modify it under the terms of the GNU General Public License
00007  as published by the Free Software Foundation; either version 2
00008  of the License, or (at your option) any later version.
00009 
00010  This program is distributed in the hope that it will be useful,
00011  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  GNU General Public License for more details.
00014 
00015  You should have received a copy of the GNU General Public License
00016  along with this program; if not, write to the Free Software
00017  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00018 
00019   Filename:  utils.c
00020  
00021   Description:  
00022  
00023   Version:  1.0
00024   Created:  06/16/07 14:56:05 CEST
00025   Revision:  
00026     0 - created (Ge@@ru)
00027     1 - created doxygen documentation and added support for
00028         opaque struct (Ge@@ru) - 11/07/07
00029 
00030   Author:   Daniele Rondina aka Ge@@ru , geaaru@gmail.com 
00031   License:  GPL 2.0
00032 */
00033 
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 // easydbus includes
00044 #include "easydbus-core.h"
00045 #include "debug.h"
00046 #include "utils.h"
00047 
00056 inline int
00057 easydbus_save_serviceName (struct EasyDbus_core *core,
00058                            char *serviceName)
00059 {
00060    int serviceNameL = 0;
00061 
00062    serviceNameL = strlen (serviceName) + 1;
00063    core->service_name = (char *) malloc (serviceNameL);
00064 
00065    if (core->service_name == NULL)
00066       return -1;
00067 
00068    EASYDBUS_MEMCOPY (core->service_name, serviceName, 
00069                      serviceNameL);
00070 
00071    return 0;
00072 }
00073 
00081 inline char *
00082 prepare_match_string (enum event_type type,
00083                       char *sender, char *interface,
00084                       char *member, char *path, char *destination)
00085 {
00086 
00087    unsigned char s, t, i, m, p, d;
00088 
00089    s = t = i = m = p = d = 0;
00090    int buffer_lenght;
00091    char *type_string = NULL;
00092    char *buffer = NULL;
00093 
00094    switch (type) {
00095       case EASYDBUS_ET_METHOD:
00096          type_string = (char *) dbus_message_type_to_string
00097             (DBUS_MESSAGE_TYPE_METHOD_CALL);
00098          t = 1;
00099          break;
00100       case EASYDBUS_ET_SIGNAL:
00101          type_string = (char *) dbus_message_type_to_string
00102             (DBUS_MESSAGE_TYPE_SIGNAL);
00103          t = 1;
00104          break;
00105       case EASYDBUS_ET_REPLY:
00106          type_string = (char *) dbus_message_type_to_string
00107             (DBUS_MESSAGE_TYPE_METHOD_RETURN);
00108          t = 1;
00109          break;
00110       case EASYDBUS_ET_FAILURE:
00111          type_string = (char *) dbus_message_type_to_string
00112             (DBUS_MESSAGE_TYPE_ERROR);
00113          t = 1;
00114          break;
00115       default:
00116          return NULL;
00117          break;
00118    }
00119 
00120    if (sender != NULL)
00121       s = 1;
00122    if (interface != NULL)
00123       i = 1;
00124    if (member != NULL)
00125       m = 1;
00126    if (path != NULL)
00127       p = 1;
00128    if (destination != NULL)
00129       d = 1;
00130 
00131    buffer_lenght =
00132       (t ? strlen (type_string) + 1 + 7 : 0) +
00133       (s ? strlen (sender) + 1 + 9 : 0) +
00134       (i ? strlen (interface) + 1 + 12 : 0) +
00135       (m ? strlen (member) + 1 + 8 : 0) +
00136       (p ? strlen (path) + 1 + 7 : 0) +
00137       (d ? strlen (destination) + 1 + 14 : 0) + 10;
00138 
00139    buffer = (char *) malloc (buffer_lenght);
00140    if (buffer == NULL)
00141       return NULL;
00142    memset (buffer, 0, buffer_lenght);
00143 
00144    snprintf (buffer, buffer_lenght,
00145              "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
00146              (t ? EASYDBUS_MATCHRULE_FOR_TYPE : ""),
00147              (t ? type_string : ""),
00148              (t ? EASYDBUS_MATCHRULE_FOR_SINGLE_QUOTE : ""),
00149              (t ? ((s || i || m || p || d) ?
00150                    EASYDBUS_MATCHRULE_FOR_COMMA : "") : ""),
00151              (s ? EASYDBUS_MATCHRULE_FOR_SENDER : ""),
00152              (s ? sender : ""),
00153              (s ? EASYDBUS_MATCHRULE_FOR_SINGLE_QUOTE : ""),
00154              (s ? ((i || m || p || d) ?
00155                    EASYDBUS_MATCHRULE_FOR_COMMA : "") : ""),
00156              (i ? EASYDBUS_MATCHRULE_FOR_INTERFACE : ""),
00157              (i ? interface : ""),
00158              (i ? EASYDBUS_MATCHRULE_FOR_SINGLE_QUOTE : ""),
00159              (i ? ((m || p || d) ?
00160                    EASYDBUS_MATCHRULE_FOR_COMMA : "") : ""),
00161              (m ? EASYDBUS_MATCHRULE_FOR_MEMBER : ""),
00162              (m ? member : ""),
00163              (m ? EASYDBUS_MATCHRULE_FOR_SINGLE_QUOTE : ""),
00164              (m ? ((p || d) ?
00165                    EASYDBUS_MATCHRULE_FOR_COMMA : "") : ""),
00166              (p ? EASYDBUS_MATCHRULE_FOR_PATH : ""),
00167              (p ? path : ""),
00168              (p ? EASYDBUS_MATCHRULE_FOR_SINGLE_QUOTE : ""),
00169              (p ? (d ? EASYDBUS_MATCHRULE_FOR_COMMA : "") : ""),
00170              (d ? EASYDBUS_MATCHRULE_FOR_DESTINATION : ""),
00171              (d ? destination : ""),
00172              (d ? EASYDBUS_MATCHRULE_FOR_SINGLE_QUOTE : ""));
00173 
00174    return buffer;
00175 }
00176 
00177 
00216 int
00217 count_elems (struct EasyDbus_elem *el,
00218              int *error, enum signature_flags flags)
00219 {
00220    struct EasyDbus_container *container;
00221    struct EasyDbus_elem *internal_el;
00222    int elems_founded = 0;
00223    unsigned int i;
00224 
00225    switch (el->type) {
00226       case EASYDBUS_ELTYPE_STRING:
00227       case EASYDBUS_ELTYPE_BYTE:
00228       case EASYDBUS_ELTYPE_BOOLEAN:
00229       case EASYDBUS_ELTYPE_DOUBLE:
00230       case EASYDBUS_ELTYPE_INT16:
00231       case EASYDBUS_ELTYPE_UINT16:
00232       case EASYDBUS_ELTYPE_INT32:
00233       case EASYDBUS_ELTYPE_UINT32:
00234       case EASYDBUS_ELTYPE_INT64:
00235       case EASYDBUS_ELTYPE_UINT64:
00236       case EASYDBUS_ELTYPE_OBJECT_PATH:
00237       case EASYDBUS_ELTYPE_SIGNATURE:
00238          //EasyDbusDebug ("founded elem\n");
00239          elems_founded++;
00240          break;
00241       case EASYDBUS_ELTYPE_VARIANT:
00242          /* variant is composed by v signature
00243           * and a normal type:
00244           * signature[..] := DBUS_TYPE_VARIANT
00245           * signature[..+1] := DBUS_TYPE_* 
00246           */
00247          if (flags & EASYDBUS_SIGNATURE_VARIANT)
00248             elems_founded += 1;
00249          elems_founded += 1;
00250          EasyDbusDebug ("founded elem %d\n", elems_founded);
00251          break;
00252       case EASYDBUS_ELTYPE_DICT_ENTRY:
00253          EasyDbusDebug ("founded elem\n");
00254          /* dict_entry is composed by:
00255           * DBUS_DICT_ENTRY_BEGIN_CHAR
00256           * + 2 elems
00257           * DBUS_DICT_ENTRY_END_CHAR */
00258          container = el->payload.p_container;
00259          elems_founded += 2;
00260          internal_el = (struct EasyDbus_elem *) container->p_data;
00261          for (i = 0; i < 2; i++) {
00262             elems_founded += count_elems (internal_el, error, flags);
00263             if (*error == 1)
00264                return 0;
00265             internal_el = internal_el->next;
00266          }
00267          break;
00268       case EASYDBUS_ELTYPE_STRUCT:
00269          // for STRUCT type it is needed
00270          // two field for 
00271          // DBUS_STRUCT_BEGIN_CHAR
00272          // DBUS_STRUCT_END_CHAR
00273          container = el->payload.p_container;
00274          elems_founded += 2;
00275          internal_el = (struct EasyDbus_elem *) container->p_data;
00276          for (i = 0; i < container->nel; i++) {
00277             EasyDbusDebug ("manage elem %d of struct\n", i + 1);
00278             elems_founded += count_elems (internal_el, error, flags);
00279             if (*error == 1)
00280                return 0;
00281             internal_el = internal_el->next;
00282             EasyDbusDebug ("founded elem %d\n", elems_founded);
00283          }
00284          EasyDbusDebug ("founded elem %d\n", elems_founded);
00285          break;
00286       case EASYDBUS_ELTYPE_INVALID:
00287          *error = 1;
00288          break;
00289       case EASYDBUS_ELTYPE_ARRAY:
00290          EasyDbusDebug ("founded elem\n");
00291          container = el->payload.p_container;
00292          elems_founded = 1;
00293          switch (container->elem_type) {
00294             case EASYDBUS_ELTYPE_ARRAY:
00295                internal_el = (struct EasyDbus_elem *)
00296                   container->p_data;
00297                for (i = 0; i < container->nel; i++) {
00298                   elems_founded +=
00299                      count_elems (internal_el, error, flags);
00300                   if (*error == 1)
00301                      return 0;
00302                   internal_el++;
00303                }
00304                EasyDbusDebug ("founded elem\n");
00305                break;
00306             case EASYDBUS_ELTYPE_STRING:
00307             case EASYDBUS_ELTYPE_BYTE:
00308             case EASYDBUS_ELTYPE_BOOLEAN:
00309             case EASYDBUS_ELTYPE_DOUBLE:
00310             case EASYDBUS_ELTYPE_INT16:
00311             case EASYDBUS_ELTYPE_UINT16:
00312             case EASYDBUS_ELTYPE_INT32:
00313             case EASYDBUS_ELTYPE_UINT32:
00314             case EASYDBUS_ELTYPE_INT64:
00315             case EASYDBUS_ELTYPE_UINT64:
00316             case EASYDBUS_ELTYPE_OBJECT_PATH:
00317             case EASYDBUS_ELTYPE_SIGNATURE:
00318                EasyDbusDebug ("founded elem\n");
00319                elems_founded++;
00320                break;
00321             case EASYDBUS_ELTYPE_VARIANT:
00322                elems_founded += 2;
00323                EasyDbusDebug ("founded elem %d\n", elems_founded);
00324                break;
00325             case EASYDBUS_ELTYPE_DICT_ENTRY:
00326                container = el->payload.p_container;
00327                elems_founded += 2;
00328                internal_el =
00329                   (struct EasyDbus_elem *) container->p_data;
00330                internal_el = internal_el->payload.p_container->p_data;
00331                for (i = 0; i < 2; i++) {
00332                   EasyDbusDebug ("founded elem %d\n", elems_founded);
00333                   elems_founded +=
00334                      count_elems (internal_el, error, flags);
00335                   if (*error == 1)
00336                      return 0;
00337                   internal_el = internal_el->next;
00338                }
00339                EasyDbusDebug ("founded elem %d\n", elems_founded);
00340                break;
00341             case EASYDBUS_ELTYPE_STRUCT:
00342                container = el->payload.p_container;
00343                internal_el =
00344                   (struct EasyDbus_elem *) container->p_data;
00345                elems_founded +=
00346                   count_elems (internal_el, error, flags);
00347                if (*error == 1)
00348                   return 0;
00349                EasyDbusDebug ("founded elem %d\n", elems_founded);
00350                break;
00351             case EASYDBUS_ELTYPE_INVALID:
00352                *error = 1;
00353                break;
00354          }
00355          break;
00356    }
00357    return elems_founded;
00358 }
00359 
00370 int
00371 count_total_elems (struct EasyDbus_elem *el, int *error)
00372 {
00373    int elems_founded = 0;
00374 
00375    *error = 0;
00376    while (el != NULL) {
00377       elems_founded += count_elems (el, error,
00378                                     EASYDBUS_SIGNATURE_NORMAL);
00379       el = el->next;
00380    }
00381    return elems_founded;
00382 }
00383 
00394 char *
00395 prepare_complete_signature (struct EasyDbus_elem *el) 
00396 {
00397    int number_of_elems = 0;
00398    int num_of_elems_from_one_node = 0;
00399    char *signature = NULL;
00400    int error = 0;
00401 
00402    if (el != NULL)
00403       number_of_elems = count_total_elems (el, &error);
00404    if (error)
00405       return NULL;
00406    EasyDbusDebug ("COUNT = %d\n", number_of_elems);
00407    signature = (char *) malloc (sizeof (char[number_of_elems + 1]));
00408    if (signature == NULL)
00409       return NULL;
00410    memset (signature, 0, number_of_elems + 1);
00411 
00412    while (el != NULL) {
00413       if (set_signature (el, signature,
00414                          num_of_elems_from_one_node,
00415                          EASYDBUS_SIGNATURE_NORMAL)) {
00416          free (signature);
00417          return NULL;
00418       }
00419       num_of_elems_from_one_node += count_elems (el, &error, 0);
00420       EasyDbusDebug ("Signature prepared for %d elems: %s",
00421           num_of_elems_from_one_node, signature);
00422       el = el->next;
00423    }
00424    EasyDbusDebug ("Signature complete prepared for %d elems: %s",
00425                   number_of_elems, signature);
00426    return signature;
00427 }
00428 
00440 char *
00441 prepare_signature (struct EasyDbus_elem *el, 
00442                    enum signature_flags flags)
00443 {
00444    int number_of_elems = 0;
00445    char *signature = NULL;
00446    int error = 0;
00447 
00448    if (el != NULL)
00449       number_of_elems = count_elems (el, &error, flags);
00450    if (error)
00451       return NULL;
00452    EasyDbusDebug ("COUNT = %d\n", number_of_elems);
00453    signature = (char *) malloc (sizeof (char[number_of_elems + 1]));
00454    if (signature == NULL)
00455       return NULL;
00456    memset (signature, 0, number_of_elems + 1);
00457 
00458    if (set_signature (el, signature, 0, flags)) {
00459       free (signature);
00460       return NULL;
00461    }
00462    EasyDbusDebug ("Signature prepared for %d elems: %s",
00463                   number_of_elems, signature);
00464    return signature;
00465 }
00466 
00485 int
00486 set_signature (struct EasyDbus_elem *el, char *signature,
00487                int offset, enum signature_flags flags)
00488 {
00489    struct EasyDbus_container *container = NULL;
00490    struct EasyDbus_elem *dict_entry = NULL;
00491    struct EasyDbus_container *dict_container = NULL;
00492    struct EasyDbus_elem *internal_el = NULL;
00493    unsigned int i;
00494    int error = 0;
00495 
00496    switch (el->type) {
00497       case EASYDBUS_ELTYPE_STRING:
00498          signature[offset] = DBUS_TYPE_STRING;
00499          break;
00500       case EASYDBUS_ELTYPE_BYTE:
00501          signature[offset] = DBUS_TYPE_BYTE;
00502          break;
00503       case EASYDBUS_ELTYPE_BOOLEAN:
00504          signature[offset] = DBUS_TYPE_BOOLEAN;
00505          break;
00506       case EASYDBUS_ELTYPE_DOUBLE:
00507          signature[offset] = DBUS_TYPE_DOUBLE;
00508          break;
00509       case EASYDBUS_ELTYPE_INT16:
00510          signature[offset] = DBUS_TYPE_INT16;
00511          break;
00512       case EASYDBUS_ELTYPE_UINT16:
00513          signature[offset] = DBUS_TYPE_UINT16;
00514          break;
00515       case EASYDBUS_ELTYPE_INT32:
00516          signature[offset] = DBUS_TYPE_INT32;
00517          break;
00518       case EASYDBUS_ELTYPE_UINT32:
00519          signature[offset] = DBUS_TYPE_UINT32;
00520          break;
00521       case EASYDBUS_ELTYPE_INT64:
00522          signature[offset] = DBUS_TYPE_INT64;
00523          break;
00524       case EASYDBUS_ELTYPE_UINT64:
00525          signature[offset] = DBUS_TYPE_UINT64;
00526          break;
00527       case EASYDBUS_ELTYPE_OBJECT_PATH:
00528          signature[offset] = DBUS_TYPE_OBJECT_PATH;
00529          break;
00530       case EASYDBUS_ELTYPE_SIGNATURE:
00531          signature[offset] = DBUS_TYPE_SIGNATURE;
00532          break;
00533       case EASYDBUS_ELTYPE_VARIANT:
00534          signature[offset] = DBUS_TYPE_VARIANT;
00535          if (flags & EASYDBUS_SIGNATURE_VARIANT) {
00536             container = el->payload.p_container;
00537             switch (container->elem_type) {
00538                case EASYDBUS_ELTYPE_STRING:
00539                   signature[offset + 1] = DBUS_TYPE_STRING;
00540                   break;
00541                case EASYDBUS_ELTYPE_BYTE:
00542                   signature[offset + 1] = DBUS_TYPE_BYTE;
00543                   break;
00544                case EASYDBUS_ELTYPE_DOUBLE:
00545                   signature[offset + 1] = DBUS_TYPE_DOUBLE;
00546                   break;
00547                case EASYDBUS_ELTYPE_BOOLEAN:
00548                   signature[offset + 1] = DBUS_TYPE_BOOLEAN;
00549                   break;
00550                case EASYDBUS_ELTYPE_INT16:
00551                   signature[offset + 1] = DBUS_TYPE_INT16;
00552                   break;
00553                case EASYDBUS_ELTYPE_UINT16:
00554                   signature[offset + 1] = DBUS_TYPE_UINT16;
00555                   break;
00556                case EASYDBUS_ELTYPE_INT32:
00557                   signature[offset + 1] = DBUS_TYPE_INT32;
00558                   break;
00559                case EASYDBUS_ELTYPE_UINT32:
00560                   signature[offset + 1] = DBUS_TYPE_UINT32;
00561                   break;
00562                case EASYDBUS_ELTYPE_INT64:
00563                   signature[offset + 1] = DBUS_TYPE_INT64;
00564                   break;
00565                case EASYDBUS_ELTYPE_UINT64:
00566                   signature[offset + 1] = DBUS_TYPE_UINT64;
00567                   break;
00568                case EASYDBUS_ELTYPE_OBJECT_PATH:
00569                   signature[offset + 1] = DBUS_TYPE_OBJECT_PATH;
00570                   break;
00571                case EASYDBUS_ELTYPE_SIGNATURE:
00572                   signature[offset + 1] = DBUS_TYPE_SIGNATURE;
00573                   break;
00574                default:
00575                   /* manage error  */
00576                   break;
00577             }
00578          }                      // end of if (flags)
00579          break;
00580       case EASYDBUS_ELTYPE_STRUCT:
00581          signature[offset] = DBUS_STRUCT_BEGIN_CHAR;
00582          container = el->payload.p_container;
00583          internal_el = (struct EasyDbus_elem *)
00584             container->p_data;
00585          i = 1;
00586          while (internal_el != NULL) {
00587             if (set_signature (internal_el, signature,
00588                                offset + i, flags))
00589                return -1;
00590             // found offset for signature of next element.
00591             i += count_elems (internal_el, &error,
00592                               EASYDBUS_SIGNATURE_NORMAL);
00593             if (error == 1)
00594                EasyDbusDebug ("Error on calculate"
00595                               " offset for signature");
00596             internal_el = internal_el->next;
00597             EasyDbusDebug ("offset = %d, i = %d", offset, i);
00598          }
00599          signature[offset + i] = DBUS_STRUCT_END_CHAR;
00600          break;
00601       case EASYDBUS_ELTYPE_DICT_ENTRY:
00602          signature[offset] = DBUS_DICT_ENTRY_BEGIN_CHAR;
00603          container = el->payload.p_container;
00604          internal_el = (struct EasyDbus_elem *)
00605             container->p_data;
00606          if (set_signature
00607              (internal_el, signature, offset + 1, flags))
00608             return -1;
00609          if (set_signature (internal_el->next,
00610                             signature, offset + 2, flags))
00611             return -1;
00612          /* signature for dict_entry with variant must indicate
00613           * only variant char not element of variant char. So,
00614           * for example for a dict entry of string and variant
00615           * char, is needed:
00616           * - a signature {sv} for dict_entry;
00617           * - a signature {vs} for variant.
00618           */
00619          if (internal_el->next->type == EASYDBUS_ELTYPE_VARIANT
00620              && (flags & EASYDBUS_SIGNATURE_VARIANT))
00621             signature[offset + 4] = DBUS_DICT_ENTRY_END_CHAR;
00622          else
00623             signature[offset + 3] = DBUS_DICT_ENTRY_END_CHAR;
00624          break;
00625       case EASYDBUS_ELTYPE_INVALID:
00626          break;
00627       case EASYDBUS_ELTYPE_ARRAY:
00628          signature[offset] = DBUS_TYPE_ARRAY;
00629          container = el->payload.p_container;
00630          switch (container->elem_type) {
00631             case EASYDBUS_ELTYPE_ARRAY:
00632                internal_el =
00633                   (struct EasyDbus_elem *) container->p_data;
00634                for (i = 0; i < container->nel; i++) {
00635                   if (set_signature (internal_el,
00636                                      signature, offset + 1, flags))
00637                      return -1;
00638                   internal_el++;
00639                }
00640                break;
00641                /* isn't possible use also set_signature() in recursive
00642                 * mode because data for string, byte, etc. on array
00643                 * are saved without struct EasyDbus_elem container 
00644                 * for limit used memory */
00645             case EASYDBUS_ELTYPE_STRING:
00646                signature[offset + 1] = DBUS_TYPE_STRING;
00647                break;
00648             case EASYDBUS_ELTYPE_BYTE:
00649                signature[offset + 1] = DBUS_TYPE_BYTE;
00650                break;
00651             case EASYDBUS_ELTYPE_BOOLEAN:
00652                signature[offset + 1] = DBUS_TYPE_BOOLEAN;
00653                break;
00654             case EASYDBUS_ELTYPE_DOUBLE:
00655                signature[offset + 1] = DBUS_TYPE_DOUBLE;
00656                break;
00657             case EASYDBUS_ELTYPE_INT16:
00658                signature[offset + 1] = DBUS_TYPE_INT16;
00659                break;
00660             case EASYDBUS_ELTYPE_UINT16:
00661                signature[offset + 1] = DBUS_TYPE_UINT16;
00662                break;
00663             case EASYDBUS_ELTYPE_INT32:
00664                signature[offset + 1] = DBUS_TYPE_INT32;
00665                break;
00666             case EASYDBUS_ELTYPE_UINT32:
00667                signature[offset + 1] = DBUS_TYPE_UINT32;
00668                break;
00669             case EASYDBUS_ELTYPE_INT64:
00670                signature[offset + 1] = DBUS_TYPE_INT64;
00671                break;
00672             case EASYDBUS_ELTYPE_UINT64:
00673                signature[offset + 1] = DBUS_TYPE_UINT64;
00674                break;
00675             case EASYDBUS_ELTYPE_OBJECT_PATH:
00676                signature[offset + 1] = DBUS_TYPE_OBJECT_PATH;
00677                break;
00678             case EASYDBUS_ELTYPE_SIGNATURE:
00679                signature[offset + 1] = DBUS_TYPE_SIGNATURE;
00680                break;
00681             case EASYDBUS_ELTYPE_VARIANT:
00682                signature[offset + 1] = DBUS_TYPE_VARIANT;
00683                if (flags & EASYDBUS_SIGNATURE_VARIANT) {
00684                   container = el->payload.p_container;
00685                   switch (container->elem_type) {
00686                      case EASYDBUS_ELTYPE_STRING:
00687                         signature[offset + 2] = DBUS_TYPE_STRING;
00688                         break;
00689                      case EASYDBUS_ELTYPE_DOUBLE:
00690                         signature[offset + 2] = DBUS_TYPE_DOUBLE;
00691                         break;
00692                      case EASYDBUS_ELTYPE_BYTE:
00693                         signature[offset + 2] = DBUS_TYPE_BYTE;
00694                         break;
00695                      case EASYDBUS_ELTYPE_BOOLEAN:
00696                         signature[offset + 2] = DBUS_TYPE_BOOLEAN;
00697                         break;
00698                      case EASYDBUS_ELTYPE_INT16:
00699                         signature[offset + 2] = DBUS_TYPE_INT16;
00700                         break;
00701                      case EASYDBUS_ELTYPE_UINT16:
00702                         signature[offset + 2] = DBUS_TYPE_UINT16;
00703                         break;
00704                      case EASYDBUS_ELTYPE_INT32:
00705                         signature[offset + 2] = DBUS_TYPE_INT32;
00706                         break;
00707                      case EASYDBUS_ELTYPE_UINT32:
00708                         signature[offset + 2] = DBUS_TYPE_UINT32;
00709                         break;
00710                      case EASYDBUS_ELTYPE_INT64:
00711                         signature[offset + 2] = DBUS_TYPE_INT64;
00712                         break;
00713                      case EASYDBUS_ELTYPE_UINT64:
00714                         signature[offset + 2] = DBUS_TYPE_UINT64;
00715                         break;
00716                      case EASYDBUS_ELTYPE_OBJECT_PATH:
00717                         signature[offset + 2] = DBUS_TYPE_OBJECT_PATH;
00718                         break;
00719                      case EASYDBUS_ELTYPE_SIGNATURE:
00720                         signature[offset + 2] = DBUS_TYPE_SIGNATURE;
00721                      default:
00722                         /* manage error  */
00723                         break;
00724                   }
00725                }                //end of if (flags)
00726                break;
00727             case EASYDBUS_ELTYPE_DICT_ENTRY:
00728                signature[offset + 1] = DBUS_DICT_ENTRY_BEGIN_CHAR;
00729                /* point to dict_entry element container */
00730                container = el->payload.p_container;
00731                dict_entry = container->p_data;
00732                /* recover dict_entry container */
00733                dict_container = dict_entry->payload.p_container;
00734                /* get first element of dict_entry container */
00735                internal_el = (struct EasyDbus_elem *)
00736                   dict_container->p_data;
00737                if (set_signature (internal_el,
00738                                   signature, offset + 2, flags))
00739                   return -1;
00740                if (set_signature (internal_el->next,
00741                                   signature, offset + 3, flags))
00742                   return -1;
00743                if ((internal_el->next->type ==
00744                     EASYDBUS_ELTYPE_VARIANT) &&
00745                    (flags & EASYDBUS_SIGNATURE_VARIANT))
00746                   signature[offset + 5] = DBUS_DICT_ENTRY_END_CHAR;
00747                else
00748                   signature[offset + 4] = DBUS_DICT_ENTRY_END_CHAR;
00749                break;
00750             case EASYDBUS_ELTYPE_STRUCT:
00751                container = el->payload.p_container;
00752                internal_el = (struct EasyDbus_elem *)
00753                   container->p_data;
00754                if (set_signature (internal_el, signature,
00755                                   offset + 1, flags))
00756                   return -1;
00757                break;
00758             case EASYDBUS_ELTYPE_INVALID:
00759                return -1;
00760                break;
00761          }                      // end of switch
00762          break;
00763    }
00764    return 0;
00765 }
00766 
00789 char *
00790 add_el_signature (enum el_type type_el,
00791                   char *old_signature, int marshal_data_status)
00792 {
00793    char *signature = NULL;
00794    int offset = 0;
00795    int signature_length = 0;
00796 
00797    if (old_signature == NULL) {
00798       signature = (char *) malloc (2);
00799       if (signature == NULL)
00800          return NULL;
00801       memset (signature, 0, 2);
00802 
00803    }
00804    else {
00805       signature_length = strlen (old_signature) + 1;
00806       signature = (char *) malloc (signature_length + 1);
00807       if (signature == NULL)
00808          return NULL;
00809       memset (signature, 0, signature_length + 1);
00810       memcpy (signature, old_signature, signature_length);
00811       offset = signature_length - 1;
00812       free (old_signature);
00813    }
00814 
00815    switch (type_el) {
00816       case EASYDBUS_ELTYPE_STRING:
00817          signature[offset] = DBUS_TYPE_STRING;
00818          break;
00819       case EASYDBUS_ELTYPE_BYTE:
00820          signature[offset] = DBUS_TYPE_BYTE;
00821          break;
00822       case EASYDBUS_ELTYPE_BOOLEAN:
00823          signature[offset] = DBUS_TYPE_BOOLEAN;
00824          break;
00825       case EASYDBUS_ELTYPE_DOUBLE:
00826          signature[offset] = DBUS_TYPE_DOUBLE;
00827          break;
00828       case EASYDBUS_ELTYPE_INT16:
00829          signature[offset] = DBUS_TYPE_INT16;
00830          break;
00831       case EASYDBUS_ELTYPE_UINT16:
00832          signature[offset] = DBUS_TYPE_UINT16;
00833          break;
00834       case EASYDBUS_ELTYPE_INT32:
00835          signature[offset] = DBUS_TYPE_INT32;
00836          break;
00837       case EASYDBUS_ELTYPE_UINT32:
00838          signature[offset] = DBUS_TYPE_UINT32;
00839          break;
00840       case EASYDBUS_ELTYPE_INT64:
00841          signature[offset] = DBUS_TYPE_INT64;
00842          break;
00843       case EASYDBUS_ELTYPE_UINT64:
00844          signature[offset] = DBUS_TYPE_UINT64;
00845          break;
00846       case EASYDBUS_ELTYPE_OBJECT_PATH:
00847          signature[offset] = DBUS_TYPE_OBJECT_PATH;
00848          break;
00849       case EASYDBUS_ELTYPE_VARIANT:
00850          signature[offset] = DBUS_TYPE_VARIANT;
00851          break;
00852       case EASYDBUS_ELTYPE_DICT_ENTRY:
00853          if (marshal_data_status)
00854             signature[offset] = DBUS_DICT_ENTRY_END_CHAR;
00855          else
00856             signature[offset] = DBUS_DICT_ENTRY_BEGIN_CHAR;
00857          break;
00858       case EASYDBUS_ELTYPE_ARRAY:
00859          signature[offset] = DBUS_TYPE_ARRAY;
00860          break;
00861       case EASYDBUS_ELTYPE_SIGNATURE:
00862          signature[offset] = DBUS_TYPE_SIGNATURE;
00863          break;
00864       case EASYDBUS_ELTYPE_STRUCT:
00865          if (marshal_data_status)
00866             signature[offset] = DBUS_STRUCT_END_CHAR;
00867          else
00868             signature[offset] = DBUS_STRUCT_BEGIN_CHAR;
00869          break;
00870       case EASYDBUS_ELTYPE_INVALID:
00871          goto error;
00872          break;
00873    }
00874 
00875    return signature;
00876 
00877  error:
00878    if (signature != NULL)
00879       free (signature);
00880    return NULL;
00881 }
00882 
00893 int
00894 easydbus_manage_list_signature (struct easydbus_signature_elem_stack *el, 
00895                                 char **signature, int flags)
00896 {
00897    enum el_type type = EASYDBUS_ELTYPE_INVALID;
00898    struct easydbus_signature_elem_stack *tmp = NULL;
00899 
00900    if (el == NULL || signature == NULL)
00901       return -1;
00902 
00903    switch (el->type) {
00904       case EASYDBUS_ELTYPE_VARIANT:
00905          if (el->next == NULL)
00906             return -1;
00907          *signature = add_el_signature (el->type, *signature, 0);
00908          /* variant element type is ignored */
00909          //container->signature = add_el_signature 
00910          // (el->next->type, container->signature, 0);
00911          EasyDbusDebug ("Ignore variant element type");
00912          easydbus_free_elem_from_stack (el->next);
00913          break;
00914       case EASYDBUS_ELTYPE_DICT_ENTRY:
00915          /* dict entry signature are managed in this way:
00916           * - EASYDBUS_ELTYPE_DICT_ENTRY +
00917           *   EASYDBUS_ELTYPE_1+ EASYDBUS_ELTYPE_2
00918           *   if elem of dict entry is a variant element, then
00919           *   also another field is inserted.
00920           */
00921          // open dict_entry
00922          *signature = add_el_signature (el->type, *signature, 0);
00923          /* check first elem (the key) */
00924          if (el->next == NULL)
00925             return -1;
00926          type = el->next->type;
00927 
00928          if (type == EASYDBUS_ELTYPE_INVALID ||
00929              type == EASYDBUS_ELTYPE_ARRAY ||
00930              type == EASYDBUS_ELTYPE_STRUCT ||
00931              type == EASYDBUS_ELTYPE_DICT_ENTRY)
00932             return -1;
00933 
00934          if (easydbus_manage_list_signature
00935              (el->next, signature, flags))
00936             return -1;
00937 
00938          /* check second elem */
00939          if (el->next->next == NULL)
00940             return -1;
00941          type = el->next->next->type;
00942 
00943          if (type == EASYDBUS_ELTYPE_INVALID ||
00944              type == EASYDBUS_ELTYPE_ARRAY ||
00945              type == EASYDBUS_ELTYPE_STRUCT ||
00946              type == EASYDBUS_ELTYPE_DICT_ENTRY)
00947             return -1;
00948 
00949          if (easydbus_manage_list_signature
00950              (el->next->next, signature, flags))
00951             return -1;
00952 
00953          /* remove dict entry elements */
00954          easydbus_free_elem_from_stack (el->next);
00955          easydbus_free_elem_from_stack (el->next);
00956 
00957          // close dict_entry 
00958          *signature = add_el_signature (el->type, *signature, 1);
00959          break;
00960       case EASYDBUS_ELTYPE_STRUCT:
00961          *signature = add_el_signature (el->type, *signature, 0);
00962          while (el->next != NULL &&
00963                 el->next->type != EASYDBUS_ELTYPE_STRUCT &&
00964                 el->next->type != EASYDBUS_ELTYPE_INVALID) {
00965             if (easydbus_manage_list_signature
00966                 (el->next, signature, flags))
00967                return -1;
00968             tmp = el->next;
00969             el->next = el->next->next;
00970             easydbus_free_elem_from_stack (tmp);
00971          }
00972          if (el->next == NULL)
00973             return -1;
00974          if (el->next->type == EASYDBUS_ELTYPE_STRUCT) {
00975             *signature = add_el_signature
00976                (el->next->type, *signature, 1);
00977          }
00978          else
00979             return -1;
00980          easydbus_free_elem_from_stack (el->next);
00981          break;
00982       case EASYDBUS_ELTYPE_ARRAY:
00983          *signature = add_el_signature (el->type, *signature, 0);
00984          if (el->next == NULL)
00985             return -1;
00986          if (easydbus_manage_list_signature (el->next,
00987                                              signature, flags))
00988             return -1;
00989          // remove array element 
00990          easydbus_free_elem_from_stack (el->next);
00991          break;
00992       case EASYDBUS_ELTYPE_INVALID:
00993          return -1;
00994          break;
00995       default:
00996          *signature = add_el_signature (el->type, *signature, 0);
00997          break;
00998    }
00999 
01000    return 0;
01001 }
01002 
01009 enum el_type
01010 get_easydbus_type_from_dbus_type (int type)
01011 {
01012    switch (type) {
01013       case DBUS_TYPE_ARRAY:
01014          return EASYDBUS_ELTYPE_ARRAY;
01015          break;
01016       case DBUS_TYPE_STRUCT:
01017          return EASYDBUS_ELTYPE_STRUCT;
01018          break;
01019       case DBUS_TYPE_VARIANT:
01020          return EASYDBUS_ELTYPE_VARIANT;
01021          break;
01022       case DBUS_TYPE_DICT_ENTRY:
01023          return EASYDBUS_ELTYPE_DICT_ENTRY;
01024          break;
01025       case DBUS_TYPE_SIGNATURE:
01026          return EASYDBUS_ELTYPE_SIGNATURE;
01027          break;
01028       case DBUS_TYPE_OBJECT_PATH:
01029          return EASYDBUS_ELTYPE_OBJECT_PATH;
01030          break;
01031       case DBUS_TYPE_DOUBLE:
01032          return EASYDBUS_ELTYPE_DOUBLE;
01033          break;
01034       case DBUS_TYPE_BOOLEAN:
01035          return EASYDBUS_ELTYPE_BOOLEAN;
01036          break;
01037       case DBUS_TYPE_BYTE:
01038          return EASYDBUS_ELTYPE_BYTE;
01039          break;
01040       case DBUS_TYPE_UINT64:
01041          return EASYDBUS_ELTYPE_UINT64;
01042          break;
01043       case DBUS_TYPE_INT64:
01044          return EASYDBUS_ELTYPE_INT64;
01045          break;
01046       case DBUS_TYPE_UINT16:
01047          return EASYDBUS_ELTYPE_UINT16;
01048          break;
01049       case DBUS_TYPE_INT16:
01050          return EASYDBUS_ELTYPE_INT16;
01051          break;
01052       case DBUS_TYPE_INT32:
01053          return EASYDBUS_ELTYPE_INT32;
01054          break;
01055       case DBUS_TYPE_UINT32:
01056          return EASYDBUS_ELTYPE_UINT32;
01057          break;
01058       case DBUS_TYPE_STRING:
01059          return EASYDBUS_ELTYPE_STRING;
01060          break;
01061       default:
01062          return EASYDBUS_ELTYPE_INVALID;
01063          break;
01064    }
01065 }
01066 
01076 inline struct EasyDbus_object_box *
01077 easydbus_get_obj (struct EasyDbus_object_box *objects,
01078                   const char *object_path)
01079 {
01080 
01081    while (objects != NULL) {
01082       if (!strcmp (object_path, objects->core.path))
01083          return objects;
01084       objects = objects->next;
01085    }
01086    return NULL;
01087 }
01088 
01089 // vim: ts=3 shiftwidth=3 expandtab

Generated on Thu Apr 10 10:00:18 2008 for EasyDbus-0.2 by  doxygen 1.5.4