summaryrefslogtreecommitdiffstats
path: root/dcopc/marshal.c
diff options
context:
space:
mode:
Diffstat (limited to 'dcopc/marshal.c')
-rw-r--r--dcopc/marshal.c420
1 files changed, 420 insertions, 0 deletions
diff --git a/dcopc/marshal.c b/dcopc/marshal.c
new file mode 100644
index 00000000..e0de9296
--- /dev/null
+++ b/dcopc/marshal.c
@@ -0,0 +1,420 @@
+/*
+Copyright (c) 2000 Simon Hausmann <hausmann@kde.org>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "marshal.h"
+
+#include <glib.h>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+dcop_data *dcop_data_new()
+{
+ dcop_data *res = g_new( dcop_data, 1 );
+
+ res->ptr = 0;
+ res->size = 0;
+ res->cur = 0;
+ res->ref = 0;
+
+ return res;
+}
+
+void dcop_data_destroy( dcop_data *data )
+{
+ g_assert( data->ref == 0 );
+
+ g_free( data->ptr );
+
+ g_free( data );
+}
+
+dcop_data *dcop_data_copy( dcop_data *data )
+{
+ dcop_data *res = dcop_data_new();
+ res->ptr = (char *)g_malloc( data->size );
+ res->size = data->size;
+ dcop_data_reset( res );
+ memcpy( res->ptr, data->ptr, data->size );
+ return res;
+}
+
+static gboolean dcop_data_check_size( dcop_data *data, unsigned int size )
+{
+ if ( data->size - ( data->cur - data->ptr ) < size )
+ return FALSE;
+ return TRUE;
+}
+
+gboolean dcop_marshal_raw( dcop_data *data, const void *ptr, unsigned int size )
+{
+ unsigned int relptr = data->cur - data->ptr;
+
+ data->ptr = (char *)g_realloc( data->ptr, data->size + size );
+
+ if ( data->ptr == 0 )
+ return FALSE;
+
+ data->cur = data->ptr + relptr;
+
+ memcpy( data->cur, ptr, size );
+
+ data->cur += size;
+ data->size += size;
+
+ return TRUE;
+}
+
+gboolean dcop_marshal_uint32( dcop_data *data, unsigned int val )
+{
+ unsigned char buf[4];
+
+ g_assert( sizeof( unsigned int ) == 4 );
+
+ buf[0] = val;
+ buf[1] = val >> 8;
+ buf[2] = val >> 16;
+ buf[3] = val >> 24;
+
+ return dcop_marshal_raw( data, buf, 4 );
+}
+
+gboolean dcop_demarshal_uint32( dcop_data *data, unsigned int *val )
+{
+ g_assert( sizeof( unsigned int ) == 4 );
+
+ if ( !dcop_data_check_size( data, 4 ) )
+ return FALSE;
+
+ *val = (data->cur[3] << 24) |
+ (data->cur[2] << 16) |
+ (data->cur[1] << 8) |
+ data->cur[0];
+ data->cur += 4;
+
+ return TRUE;
+}
+
+gboolean dcop_marshal_string( dcop_data *data, const gchar *str )
+{
+ size_t l = 0;
+
+ if ( str )
+ l = strlen( str ) + 1;
+
+ if( !dcop_marshal_uint32( data, l ) )
+ return FALSE;
+
+ if ( str )
+ return dcop_marshal_raw( data, str, l );
+ else
+ return TRUE;
+}
+
+gboolean dcop_demarshal_string( dcop_data *data, gchar **str )
+{
+ unsigned int l = 0;
+ gchar *res = 0;
+
+ g_assert( str );
+
+ if ( !dcop_demarshal_uint32( data, &l ) )
+ return FALSE;
+
+ if ( !dcop_data_check_size( data, l ) )
+ return FALSE;
+
+ res = (char *)g_malloc( l );
+ memcpy( res, data->cur, l );
+ data->cur += l;
+
+ *str = res;
+
+ return TRUE;
+}
+
+
+gboolean dcop_marshal_string16( dcop_data *data, const gchar *str )
+{
+ size_t l = 0;
+ size_t c = 0;
+ char *tmp = 0;
+ const char *src = str;
+ char *dst = 0;
+
+ if ( str )
+ l = strlen( str ) * 2;
+ else
+ {
+ /* null marker*/
+ guint32 s = 0xffffffff;
+ return dcop_marshal_uint32( data, s );
+ }
+
+ if( !dcop_marshal_uint32( data, l ) )
+ return FALSE;
+
+ if ( str )
+ {
+ dst = tmp = (char *)g_malloc( l );
+ c = strlen( str );
+
+ while ( c-- )
+ {
+ *dst++ = 0;
+ *dst++ = *src++;
+ }
+
+ dcop_marshal_raw( data, tmp, l );
+
+ g_free( tmp );
+ }
+ return TRUE;
+}
+
+gboolean dcop_demarshal_string16( dcop_data *data, gchar **str )
+{
+ unsigned int l = 0;
+ unsigned int size = 0;
+ char *res = 0;
+ char *p = 0;
+
+ assert( str );
+
+ if ( !dcop_demarshal_uint32( data, &l ) )
+ return FALSE;
+
+ /* null marker*/
+ if ( l == 0xffffffff )
+ {
+ *str = 0;
+ return TRUE;
+ }
+
+ if ( !dcop_data_check_size( data, l ) )
+ return FALSE;
+
+ size = ( l / 2 );
+
+ p = res = (char *)g_malloc( size + 1 );
+
+ while( size-- )
+ {
+ data->cur++;
+ *p++ = *data->cur++;
+ }
+
+ *p = '\0';
+
+ *str = res;
+
+ return TRUE;
+}
+
+gboolean dcop_marshal_bytearray( dcop_data *data, const gchar *str, size_t size )
+{
+ if( !dcop_marshal_uint32( data, size ) )
+ return FALSE;
+
+ if ( str )
+ return dcop_marshal_raw( data, str, size );
+ else
+ return TRUE;
+}
+
+gboolean dcop_demarshal_bytearray( dcop_data *data, gchar **str, size_t *size )
+{
+ unsigned int l = 0;
+ gchar *res = 0;
+
+ g_assert( str );
+
+ if ( !dcop_demarshal_uint32( data, &l ) )
+ return FALSE;
+
+ if ( !dcop_data_check_size( data, l ) )
+ return FALSE;
+
+ res = (char *)g_malloc( l );
+ memcpy( res, data->cur, l );
+ data->cur += l;
+
+ *str = res;
+ *size = l;
+
+ return TRUE;
+}
+
+
+
+gboolean dcop_marshal_data( dcop_data *data, dcop_data *other )
+{
+ if ( !dcop_marshal_uint32( data, other->size ) )
+ return FALSE;
+
+ return dcop_marshal_raw( data, other->ptr, other->size );
+}
+
+gboolean dcop_demarshal_data( dcop_data *data, dcop_data **other )
+{
+ dcop_data *res = dcop_data_new();
+ char *tmp = 0;
+ unsigned int l = 0;
+
+ if ( !dcop_demarshal_uint32( data, &l ) )
+ return FALSE;
+
+ if ( !dcop_data_check_size( data, l ) )
+ return FALSE;
+
+ tmp = (char *)malloc( l );
+
+ memcpy( tmp, data->cur, l );
+ data->cur += l;
+
+ dcop_data_assign( res, tmp, l );
+ dcop_data_ref( res );
+
+ *other = res;
+ return True;
+}
+
+gboolean dcop_marshal_stringlist( dcop_data *data, GList *list )
+{
+ GList *it = g_list_first( list );
+
+ if ( !dcop_marshal_uint32( data, g_list_length( list ) ) )
+ return FALSE;
+
+ while ( it )
+ {
+ if ( !dcop_marshal_string( data, (gchar *)it->data ) )
+ return FALSE;
+ it = g_list_next( it );
+ }
+ return TRUE;
+}
+
+gboolean dcop_demarshal_stringlist( dcop_data *data, GList**list )
+{
+ unsigned int count = 0;
+ GList *res = 0;
+ unsigned int i = 0;
+ gchar *str = 0;
+
+ *list = 0;
+
+ if ( !dcop_demarshal_uint32( data, &count ) )
+ return FALSE;
+
+ for ( i = 0; i < count; ++i )
+ {
+ if ( !dcop_demarshal_string( data, &str ) )
+ {
+ dcop_list_free( res );
+ return FALSE;
+ }
+ res = g_list_append( res, str );
+ }
+ *list = res;
+ return TRUE;
+}
+
+gboolean dcop_marshal_stringlist16( dcop_data *data, GList *list )
+{
+ GList *it = g_list_first( list );
+
+ if ( !dcop_marshal_uint32( data, g_list_length( list ) ) )
+ return False;
+
+ while ( it )
+ {
+ if ( !dcop_marshal_string16( data, (gchar *)it->data ) )
+ return FALSE;
+ it = g_list_next( it );
+ }
+ return TRUE;
+}
+
+gboolean dcop_demarshal_stringlist16( dcop_data *data, GList **list )
+{
+ unsigned int count = 0;
+ GList *res = 0;
+ unsigned int i = 0;
+ char *str = 0;
+
+ *list = 0;
+
+ if ( !dcop_demarshal_uint32( data, &count ) )
+ return FALSE;
+
+ for ( i = 0; i < count; ++i )
+ {
+ if ( !dcop_demarshal_string16( data, &str ) )
+ {
+ dcop_list_free( res );
+ return FALSE;
+ }
+ res = g_list_append( res, str );
+ }
+ *list = res;
+ return TRUE;
+}
+
+void dcop_data_assign( dcop_data *data, char *d, unsigned int size )
+{
+ data->ptr = data->cur = d;
+ data->size = size;
+}
+
+gboolean dcop_marshal_boolean( dcop_data *data, gboolean val )
+{
+ guint8 i = (guint8)val;
+ return dcop_marshal_uint8( data, i );
+}
+
+gboolean dcop_demarshal_boolean( dcop_data *data, gboolean *val )
+{
+ guint8 i;
+ if ( !dcop_demarshal_uint8( data, &i ) )
+ return FALSE;
+ *val = (gboolean)i;
+ return TRUE;
+}
+
+gboolean dcop_marshal_uint8( dcop_data *data, guint8 val )
+{
+ return dcop_marshal_raw( data, &val, 1 );
+}
+
+gboolean dcop_demarshal_uint8( dcop_data *data, guint8 *val )
+{
+ if ( !dcop_data_check_size( data, 1 ) )
+ return FALSE;
+
+ *val = *data->cur++;
+ return TRUE;
+}
+
+dcop_data *dcop_data_ref( dcop_data *data ) { data->ref++; return data; }
+void dcop_data_deref( dcop_data *data ) { if ( !--data->ref ) dcop_data_destroy( data ); }
+void dcop_data_reset( dcop_data *data ) { data->cur = data->ptr; }