OpenSync 0.22
opensync/opensync_serializer.c
00001 #include "opensync.h"
00002 #include "opensync_internals.h"
00003 
00004 int osync_marshal_get_size_changetype( OSyncChangeType changetype )
00005 {
00006   return sizeof( int );
00007 }
00008 
00009 void osync_marshal_changetype( OSyncMessage *message, OSyncChangeType changetype )
00010 {
00011   osync_message_write_int( message, (int)changetype );
00012 }
00013 
00014 void osync_demarshal_changetype( OSyncMessage *message, OSyncChangeType *changetype )
00015 {
00016   int change_type = 0;
00017 
00018   osync_message_read_int( message, &change_type );
00019   *changetype =(OSyncChangeType)change_type;
00020 }
00021 
00022 int osync_marshal_get_size_change( OSyncChange *change )
00023 {
00024   int size = 0;
00025 
00026   if ( !change )
00027     return size;
00028 
00029   size += strlen( change->uid );
00030   size += strlen( change->hash );
00031   size += sizeof( int ); // change->size
00032   size += change->size;  // change->data
00033   size += sizeof( int ); // change->has_data
00034   size += strlen( change->objtype_name );
00035   size += strlen( change->format_name );
00036   size += strlen( change->initial_format_name );
00037   size += osync_marshal_get_size_changetype( change->changetype );
00038   size += sizeof( long long int ); // change->id
00039   size += strlen( change->destobjtype );
00040   size += strlen( change->sourceobjtype );
00041   size += osync_marshal_get_size_member( change->sourcemember );
00042 
00043   return size;
00044 }
00045 
00046 void osync_marshal_changedata(OSyncMessage *message, OSyncChange *change)
00047 {
00048         OSyncObjFormat *format = osync_change_get_objformat(change);
00049         char *data;
00050         int datasize;
00051         int free_data = 0;
00052 
00053         osync_message_write_int( message, change->has_data );
00054 
00055         if (change->data && format && format->marshall_func) {
00056                 format->marshall_func(change->data, change->size, &data, &datasize, NULL);
00057                 /*FIXME: Handle errors on marshall_func */
00058                 free_data = 1;
00059         } else {
00060                 /* If the format is a plain format, then we have to add
00061                  * one byte for \0 to the datasize. This extra byte will
00062                  * be removed by the osync_demarshal_changedata funciton.
00063                  */
00064                 data = change->data;
00065                 datasize = change->size;
00066                 datasize++;
00067         }
00068 
00069         if (!data)
00070                 datasize = 0;
00071 
00072         osync_message_write_int(message, datasize);
00073         if (datasize > 0)
00074                 osync_message_write_data(message, data, datasize);
00075 
00076         if (free_data)
00077                 g_free(data);
00078 }
00079 
00080 void osync_marshal_change( OSyncMessage *message, OSyncChange *change )
00081 {
00082   osync_message_write_string( message, change->uid );
00083   osync_message_write_string( message, change->hash );
00084 
00085   char *format_name = change->format ? change->format->name : change->format_name;
00086   char *objtype_name = change->objtype ? change->objtype->name : change->objtype_name;
00087   char *initial_format_name = change->initial_format ? change->initial_format->name : change->initial_format_name;
00088   osync_message_write_string( message, objtype_name );
00089   osync_message_write_string( message, format_name );
00090   osync_message_write_string( message, initial_format_name );
00091 
00092   osync_marshal_changedata(message, change);
00093 
00094   osync_marshal_changetype( message, change->changetype );
00095   osync_message_write_long_long_int( message, change->id );
00096   osync_message_write_string( message, change->destobjtype );
00097   osync_message_write_string( message, change->sourceobjtype );
00098   osync_marshal_member( message, change->sourcemember );
00099 }
00100 
00101 void osync_demarshal_changedata(OSyncMessage *message, OSyncChange *change)
00102 {
00103         OSyncObjFormat *format = osync_change_get_objformat(change);
00104         char *data;
00105         int datasize;
00106 
00107         osync_message_read_int( message, &( change->has_data ) );
00108 
00109         osync_message_read_int(message, &datasize);
00110         if (datasize > 0) {
00111                 data = malloc(datasize);
00112                 osync_message_read_data( message, data, datasize );
00113 
00114                 if (format && format->demarshall_func) {
00115                         char *newdata;
00116                         int newsize;
00117                         format->demarshall_func(data, datasize, &newdata, &newsize, NULL);
00118                         /*FIXME: Handle errors on demarshall_func */
00119                         free(data);
00120                         data = newdata;
00121                         datasize = newsize;
00122                 } else {
00123                         /* If the format is a plain, then we have to remove
00124                          * one from the datasize, since once one was added by 
00125                          * osync_marshall_changedata() for trailing newline.
00126                          */
00127                         datasize--;
00128                 }
00129         } else {
00130                 data = NULL;
00131         }
00132 
00133         change->data = data;
00134         change->size = datasize;
00135 }
00136 
00137 void osync_demarshal_change( OSyncMessage *message, OSyncFormatEnv *conv_env, OSyncChange **change )
00138 {
00139   OSyncChange *new_change = osync_change_new();
00140 
00141   osync_change_set_conv_env(new_change, conv_env);
00142 
00143   osync_message_read_string( message, &( new_change->uid ) );
00144   osync_message_read_string( message, &( new_change->hash ) );
00145 
00146   osync_message_read_string( message, &( new_change->objtype_name ) );
00147   osync_message_read_string( message, &( new_change->format_name ) );
00148   osync_message_read_string( message, &( new_change->initial_format_name ) );
00149 
00150   osync_demarshal_changedata(message, new_change);
00151 
00152   osync_demarshal_changetype( message, &( new_change->changetype ) );
00153   osync_message_read_long_long_int( message, &( new_change->id ) );
00154   osync_message_read_string( message, &( new_change->destobjtype ) );
00155   osync_message_read_string( message, &( new_change->sourceobjtype ) );
00156   osync_demarshal_member( message, &( new_change->sourcemember ) );
00157 
00158   new_change->member = 0;
00159   new_change->engine_data = 0;
00160   new_change->mappingid = 0;
00161   new_change->changes_db = 0;
00162 
00163   *change = new_change;
00164 }
00165 
00166 int osync_marshal_get_size_member( OSyncMember *member )
00167 {
00168   return sizeof( int );
00169 }
00170 
00171 void osync_marshal_member( OSyncMessage *message, OSyncMember *member )
00172 {
00173   if ( member ) {
00174     osync_message_write_int( message, member->id );
00175   } else {
00176     osync_message_write_int( message, -1 );
00177   }
00178 }
00179 
00180 void osync_demarshal_member( OSyncMessage *message, OSyncMember **member )
00181 {
00182   int id;
00183 
00184   osync_message_read_int( message, &id );
00185 
00186   if ( id == -1 )
00187     *member = 0;
00188   else {
00189     //TODO: search in pool
00190   }
00191 }
00192 
00193 int osync_marshal_get_size_error( OSyncError **error )
00194 {
00195   int size = 0;
00196 
00197   if ( !osync_error_is_set(error) )
00198     return size;
00199 
00200   size += sizeof( int );
00201   size += strlen( (*error)->message );
00202 
00203   return size;
00204 }
00205 
00206 void osync_marshal_error( OSyncMessage *message, OSyncError *error )
00207 {
00208         if (error) {
00209                 osync_message_write_int( message, 1 );
00210                 osync_message_write_int( message, (int)error->type );
00211                 osync_message_write_string( message, error->message );
00212         } else {
00213                 osync_message_write_int( message, 0 );
00214         }
00215 }
00216 
00217 void osync_demarshal_error( OSyncMessage *message, OSyncError **error )
00218 {
00219         int hasError = 0;
00220 
00221         osync_message_read_int( message, &hasError );
00222         
00223         if (hasError) {
00224                 char *msg;
00225                 int error_type;
00226                 
00227                 osync_message_read_int( message, &error_type );
00228                 osync_message_read_string( message, &msg );
00229                 
00230                 osync_error_set( error, (OSyncErrorType)error_type, msg );
00231         } else
00232                 osync_error_free(error);
00233 }
00234 
00235 /*FIXME: review these get_size_*() functions
00236  *
00237  * - check if the data is being marhsalled as specified in the functions
00238  * - check (proabably invalid) usage of strlen() without considering the
00239  *   string length bytes and the nul terminator
00240  */
00241 int osync_marshal_get_size_message( OSyncMessage *message )
00242 {
00243   int size = 0;
00244 
00245   if ( !message )
00246     return size;
00247 
00248   size += sizeof( int ); // message->cmd
00249   size += sizeof( long long int ); // message->id
00250   size += sizeof( int ); // has error
00251 
00252   return 0;
00253 }