GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members  

GATXdsWrapper.c

Go to the documentation of this file.
00001 /** @file GATXds.c
00002  *  Source file for the GAT xds wrapper functions.
00003  *
00004  *  @date Thu Oct 30 2003
00005  *
00006  *  @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATXdsWrapper.c,v 1.23 2004/05/10 15:17:32 hartmutkaiser Exp $
00007  *
00008  *  Copyright (C) Hartmut Kaiser
00009  *  This file is part of the GAT Engine.
00010  *  Contributed by Hartmut Kaiser <hartmutkaiser [at] t-online [dot] de>.
00011  *
00012  *  Use, modification and distribution is subject to the Gridlab Software
00013  *  License. (See accompanying file GLlicense.txt or copy at
00014  *  http://www.gridlab.org/GLlicense.txt)
00015  */
00016  
00017 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATXdsWrapper.c,v 1.23 2004/05/10 15:17:32 hartmutkaiser Exp $";
00018 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <stdarg.h>
00022 #include <string.h>
00023 #include <assert.h>
00024 
00025 #include "xds_p.h"
00026 #include "uuid.h"
00027 
00028 #include "GAT.h"
00029 #include "GATXdsWrapper.h"
00030 #include "GATMemoryStream.h"
00031 
00032 /* local function declarations */
00033 static int 
00034 xml_encode_object(xds_t *xds, void *engine_context, void *buffer, 
00035   size_t buffer_size, size_t *used_buffer_size, va_list *args);
00036   
00037 static int 
00038 xml_decode_object(xds_t *xds, void *engine_context, void *buffer, 
00039   size_t buffer_size, size_t *used_buffer_size, va_list *args);
00040   
00041 static int 
00042 xml_encode_double_fmt(xds_t *xds, void *engine_context, void *buffer, 
00043   size_t buffer_size, size_t *used_buffer_size, va_list *args);
00044   
00045 static int 
00046 xml_decode_double_fmt(xds_t *xds, void *engine_context, void *buffer, 
00047   size_t buffer_size, size_t *used_buffer_size, va_list *args);
00048   
00049 
00050 /* external functions */
00051 
00052 /** GATXds_Init
00053  *  
00054  *  The function GATXds_Init initialises a new instance of the 
00055  *  underlying XDS engine and registers all the streaming functions to be used 
00056  *  by subsequent streaming operations via GATXds_Encode or 
00057  *  GATXds_Decode.
00058  *
00059  *  @param xds The pointer to a variable, which receives the initialised xds 
00060  *        handle.
00061  *  @param type Defines, whether the returned engine is to be used for 
00062  *        serialisation (type == GATXdsType_Encode) or de-serialisation 
00063  *        (type == GATXdsType_Decode).
00064  *
00065  *  @returns An error code.
00066  */
00067 GATResult 
00068 GATXds_Init(GATXds *xds, GATXdsType type)
00069 {
00070   return GATXds_InitEx(xds, type, 0);
00071 }
00072 
00073 GATResult 
00074 GATXds_InitEx(GATXds *xds, GATXdsType type, GATContext context)
00075 {
00076   /* TODO: Register the other required streaming functions too */
00077   GATResult retval = GAT_INVALID_PARAMETER;
00078   if (GATXdsType_Encode == type)
00079   {
00080     if (XDS_OK != (retval = xds_init(xds, XDS_ENCODE)) ||
00081       XDS_OK != (retval = xds_register(*xds, "object", &xml_encode_object, 0)) ||
00082       XDS_OK != (retval = xds_register(*xds, "string", &xml_encode_string, 0)) ||
00083       XDS_OK != (retval = xds_register(*xds, "octet", &xml_encode_octetstream, 0)) ||
00084       XDS_OK != (retval = xds_register(*xds, "double", &xml_encode_double, 0)) ||
00085       XDS_OK != (retval = xds_register(*xds, "double_fmt", &xml_encode_double_fmt, 0)) ||
00086       XDS_OK != (retval = xds_register(*xds, "float", &xml_encode_float, 0)) ||
00087       XDS_OK != (retval = xds_register(*xds, "int32", &xml_encode_int32, 0)) ||
00088       XDS_OK != (retval = xds_register(*xds, "uint32", &xml_encode_uint32, 0)) ||
00089       XDS_OK != (retval = xds_register(*xds, "int64", &xml_encode_int64, 0)) ||
00090       XDS_OK != (retval = xds_register(*xds, "uint64", &xml_encode_uint64, 0)))
00091     {
00092       retval = XDS_TO_GAT(retval);
00093     }
00094     else
00095     {
00096       retval = GAT_SUCCESS;
00097     }
00098   }
00099   else if (GATXdsType_Decode == type)
00100   {
00101     if (XDS_OK != (retval = xds_init(xds, XDS_DECODE)) ||
00102       XDS_OK != (retval = xds_register(*xds, "object", &xml_decode_object, context)) ||
00103       XDS_OK != (retval = xds_register(*xds, "string", &xml_decode_string, 0)) ||
00104       XDS_OK != (retval = xds_register(*xds, "octet", &xml_decode_octetstream, 0)) ||
00105       XDS_OK != (retval = xds_register(*xds, "double", &xml_decode_double, 0)) ||
00106       XDS_OK != (retval = xds_register(*xds, "float", &xml_decode_float, 0)) ||
00107       XDS_OK != (retval = xds_register(*xds, "int32", &xml_decode_int32, 0)) ||
00108       XDS_OK != (retval = xds_register(*xds, "uint32", &xml_decode_uint32, 0)) ||
00109       XDS_OK != (retval = xds_register(*xds, "int64", &xml_decode_int64, 0)) ||
00110       XDS_OK != (retval = xds_register(*xds, "uint64", &xml_decode_uint64, 0)))
00111     {
00112       retval = XDS_TO_GAT(retval);
00113     }
00114     else
00115     {
00116       retval = GAT_SUCCESS;
00117     }
00118   }
00119   return retval;
00120 }
00121 
00122 /** GATXds_Destroy
00123  *  
00124  *  The function GATXds_Destroy frees all the memory used by the XDS 
00125  *  engine.
00126  *
00127  *  @param xds The XDS engine handle to destroy.
00128  */
00129 void 
00130 GATXds_Destroy(GATXds *xds)
00131 {
00132   if (NULL != xds && NULL != *xds)
00133   {
00134     xds_destroy(*xds);
00135     *xds = NULL;
00136   }
00137 }
00138 
00139 /** GATXds_Encode
00140  *
00141  *  The function GATXds_Encode encodes the given data items accordingly 
00142  *  to the given format description and returns the streamed data through the 
00143  *  supplied buffer variable.
00144  *
00145  *  @param xds The handle of the XDS engine to use.
00146  *  @param flag This defines the ownership of the returned buffer. If 
00147  *        flag == GATXdsScope_Gift, the returned buffer is to be freed by the 
00148  *        caller, If flag == GATXdsScope_Loan, the returned buffer memory is 
00149  *        maintained by the XDS engine.
00150  *  @param buffer The pointer to a variable, where the buffer is to be 
00151  *        returned. If this parameter is zero, no buffer is returned and may
00152  *        be requested in a subsequent call to GATXds_Encode.
00153  *  @param buffer_len This receives the size of the returned buffer.
00154  *  @param fmt A format description, which defines the data format of all 
00155  *        subsequent parameters.
00156  *  @param ... An arbitrary amount of data items to stream.
00157  *
00158  *  @return An error code.
00159  */
00160 GATResult 
00161 GATXds_Encode(GATXds xds, GATXdsScope flag, void **buffer, 
00162   size_t *buffer_len, const char *fmt, ...)
00163 {
00164   GATResult retval = XDS_ERR_UNKNOWN;
00165   va_list args;
00166   
00167   va_start(args, fmt);
00168   if (XDS_OK != (retval = xds_vencode(xds, fmt, args)))
00169   {
00170     retval = XDS_TO_GAT(retval);
00171   }
00172   else if (NULL != buffer)
00173   {
00174     /* get the buffer from the xds engine only, if requested */
00175     assert(GATXdsScope_Gift == flag || GATXdsScope_Loan == flag);
00176     assert(NULL != buffer_len);
00177     if (XDS_OK != (retval = xds_getbuffer(xds, (xds_scope_t)flag, buffer, buffer_len)))
00178     {
00179       retval = XDS_TO_GAT(retval);
00180     }
00181     else
00182     {
00183       retval = GAT_SUCCESS;
00184     }
00185   }
00186   else
00187   {
00188     retval = GAT_SUCCESS;
00189   }
00190   return retval;
00191 }
00192 
00193 GATResult 
00194 GATXds_EncodeV(GATXds xds, GATXdsScope flag, void **buffer, 
00195   size_t *buffer_len, const char *fmt, va_list args)
00196 {
00197   GATResult retval = XDS_ERR_UNKNOWN;
00198   if (XDS_OK != (retval = xds_vencode(xds, fmt, args)))
00199   {
00200     retval = XDS_TO_GAT(retval);
00201   }
00202   else if (NULL != buffer)
00203   {
00204     /* get the buffer from the xds engine only, if requested */
00205     assert(GATXdsScope_Gift == flag || GATXdsScope_Loan == flag);
00206     assert(NULL != buffer_len);
00207     if (XDS_OK != (retval = xds_getbuffer(xds, (xds_scope_t)flag, buffer, buffer_len)))
00208     {
00209       retval = XDS_TO_GAT(retval);
00210     }
00211     else
00212     {
00213       retval = GAT_SUCCESS;
00214     }
00215   }
00216   else
00217   {
00218     retval = GAT_SUCCESS;
00219   }
00220   return retval;
00221 }
00222 
00223 /** GATXds_Decode
00224  *
00225  *  The function GATXds_Decode decodes the required amount of data items
00226  *  accordingly to the given format description.
00227  *
00228  *  @param xds The handle of the XDS engine to use.
00229  *  @param flag This defines the ownership of given returned buffer. If 
00230  *        flag == GATXdsScope_Gift, the returned buffer is to be freed by the 
00231  *        XDS engine, If flag == GATXdsScope_Loan, the supplied buffer memory 
00232  *        is maintained by the caller.
00233  *  @param buffer The buffer containing the streamed data. If this parameter is
00234  *        zero, the existing buffer is reused and the decoding continues at the
00235  *        point, where a previous decode ended.
00236  *  @param buffer_len The size of the supplied buffer.
00237  *  @param fmt A format description, which defines the data format of all 
00238  *        subsequent parameters.
00239  *  @param ... An arbitrary amount of data item addresses to decode from the 
00240  *        stream.
00241  *
00242  *  @return An error code.
00243  */
00244 GATResult 
00245 GATXds_Decode(GATXds xds, GATXdsScope flag, void *buffer, 
00246   size_t buffer_len, const char *fmt, ...)
00247 {
00248   GATResult retval = XDS_ERR_UNKNOWN;
00249 
00250   /* set a new buffer only if given */
00251   if (NULL == buffer ||
00252     XDS_OK == (retval = xds_setbuffer(xds, (xds_scope_t)flag, buffer, buffer_len)))
00253   {
00254     /* read in the required data */
00255     va_list args;
00256     
00257     va_start(args, fmt);
00258     retval = xds_vdecode(xds, fmt, args);
00259   }
00260 
00261   if (XDS_OK != retval)
00262   {
00263     retval = XDS_TO_GAT(retval);
00264   }
00265   else
00266   {
00267     retval = GAT_SUCCESS;
00268   }
00269   return retval;
00270 }
00271 
00272 GATResult 
00273 GATXds_DecodeV(GATXds xds, GATXdsScope flag, void *buffer, 
00274   size_t buffer_len, const char *fmt, va_list args)
00275 {
00276   GATResult retval = XDS_ERR_UNKNOWN;
00277 
00278   /* set a new buffer only if given */
00279   if (NULL == buffer ||
00280     XDS_OK == (retval = xds_setbuffer(xds, (xds_scope_t)flag, buffer, buffer_len)))
00281   {
00282     /* read in the required data */
00283     retval = xds_vdecode(xds, fmt, args);
00284   }
00285 
00286   if (XDS_OK != retval)
00287   {
00288     retval = XDS_TO_GAT(retval);
00289   }
00290   else
00291   {
00292     retval = GAT_SUCCESS;
00293   }
00294   return retval;
00295 }
00296 
00297 /** GATXds_GetBufferLen
00298  *
00299  *  The function GATXds_GetBufferLen may be used to retrieve the real
00300  *  amount of data decoded by the last call to GATXds_Decode.
00301  *
00302  *  @param xds The handle of the XDS engine to use.
00303  *
00304  *  @return The offset into the buffer, up to which the data was decoded 
00305  *        successful.
00306  */
00307 size_t 
00308 GATXds_GetBufferLen(GATXds xds)
00309 {
00310   return xds->buffer_len;
00311 }
00312 
00313 /** GATXds_GetBufferLen
00314  *
00315  *  The function GATXds_GetBufferCapacity may be used to retrieve the 
00316  *  capacity of the buffer inside the XDS engine.
00317  *
00318  *  @param xds The handle of the XDS engine to use.
00319  *
00320  *  @return The buffer capacity.
00321  */
00322 size_t 
00323 GATXds_GetBufferCapacity(GATXds xds)
00324 {
00325   return xds->buffer_capacity;
00326 }
00327 
00328 /** GATXds_GetBuffer
00329  *
00330  *  The GATXds_GetBuffer may be called to get access to the buffer stored 
00331  *  inside the XDS engine.
00332  *
00333  *  @param xds The handle of the XDS engine to use.
00334  *  @param flag This defines the ownership of given returned buffer. If 
00335  *        flag == GATXdsScope_Gift, the returned buffer is to be freed by the 
00336  *        XDS engine, If flag == GATXdsScope_Loan, the supplied buffer memory 
00337  *        is maintained by the caller.
00338  *  @param buffer The pointer to a variable, where the buffer is to be 
00339  *        returned. If this parameter is zero, no buffer is returned and may
00340  *        be requested in a subsequent call to GATXds_Encode.
00341  *  @param buffer_len This receives the size of the returned buffer.
00342  *
00343  *  @return An error code.
00344  */
00345 GATResult 
00346 GATXds_GetBuffer(GATXds xds, GATXdsScope flag, void **buffer, 
00347   size_t *buffer_size)
00348 {
00349   GATResult retval = GAT_FAIL;
00350   int xds_error = xds_getbuffer(xds, (xds_scope_t)flag, buffer, buffer_size);
00351   if (XDS_OK == xds_error)
00352   {
00353     retval = GAT_SUCCESS;
00354   }
00355   else
00356   {
00357     retval = XDS_TO_GAT(xds_error);
00358   }
00359   return retval;
00360 }
00361 
00362 /** GATXds_SerialiseObject
00363  *
00364  *  The function GATXds_SerialiseObject is a helper function for serialisation
00365  *  of a GATObject, which calls back to the caller (through the callback 
00366  *  argument) to serialize the data of the associated CPI provider.
00367  *
00368  *  @param object The object to serialise. This is passed through to the 
00369  *        callback function.
00370  *  @param stream The stream interface to use for the serialisation.
00371  *  @param clear_dirty If the clear_dirty parameter is set to GATTrue, the 
00372  *        internal dirty flag of this object is to be reset (no used here)
00373  *        This is passed through to the callback function.
00374  *  @param fmt The format string for the serialisation of the supplied
00375  *        data items. This format should start with "uint32" for the version
00376  *        of the object.
00377  *  @param ... The data items to serialise for the given object. The first of 
00378  *        this items should be the version of the object.
00379  *
00380  *  @return An error code.
00381  */
00382 GATResult
00383 GATXds_SerialiseObject(GATObject object, GATObject stream, GATBool clear_dirty,
00384   GATXdsSerialiseCallback callback, char const *fmt, ...)
00385 {
00386   GATResult retval = GAT_FAIL;
00387   GATXds xds = NULL;
00388   void *xds_buffer = NULL;
00389   GATuint32 xds_buffer_size = 0;
00390   va_list args;
00391 
00392   va_start(args, fmt);
00393   if (GAT_SUCCESS == (retval = GATXds_Init(&xds, GATXdsType_Encode)) &&
00394       GAT_SUCCESS == (retval = GATXds_EncodeV(xds, GATXdsScope_Gift,
00395         &xds_buffer, &xds_buffer_size, fmt, args)))
00396   {
00397     /* write the buffer len to ease de-serialisation */
00398     void *xds_size_buffer = NULL;
00399     GATuint32 xds_size_buffer_size = 0;
00400     
00401     if (GAT_SUCCESS == (retval = GATXds_Encode(xds, GATXdsScope_Gift,
00402         &xds_size_buffer, &xds_size_buffer_size, "uint32", xds_buffer_size)))
00403     {
00404       assert(NULL != xds_size_buffer);
00405       retval = GATStreamable_Write(stream, xds_size_buffer, 
00406         xds_size_buffer_size, 0);
00407       if (GAT_SUCCESS == retval)
00408       {
00409         /* write the buffer itself */
00410         assert(NULL != xds_buffer);
00411         retval = GATStreamable_Write(stream, xds_buffer, xds_buffer_size, 0);
00412       }
00413       
00414       if (GAT_SUCCESS == retval && NULL != callback)
00415       {
00416         /* call the associated CPI provider to save its instance data */
00417         retval = callback(object, stream, clear_dirty);
00418       }
00419     }
00420     
00421     free(xds_size_buffer);
00422   }
00423   
00424   GATXds_Destroy(&xds);
00425   free(xds_buffer);
00426   return retval;
00427 }
00428 
00429 /** GATXds_DeSerialiseObject
00430  *
00431  *  The function GATXds_DeSerialiseObject
00432  *
00433  *  @return An error code.
00434  */
00435 GATResult
00436 GATXds_DeSerialiseObject(GATContext context, GATObject stream, 
00437   GATXdsDeSerialiseCallback callback, GATXdsVersionCallback version_callback,
00438   GATObject *object, char const *fmt, ...)
00439 {
00440   char buffer[64];          /* seems to be sufficient for a GATuint32 value */
00441   GATuint32 xds_read_bytes = 0;
00442   GATResult retval = GATStreamable_Read(stream, buffer, sizeof(buffer), 
00443     &xds_read_bytes);
00444 
00445   if (GAT_SUCCESS == retval)
00446   {
00447     GATXds xds = NULL;
00448 
00449     if (GAT_SUCCESS == (retval = GATXds_InitEx(&xds, GATXdsType_Decode, context)))
00450     {
00451       GATuint32 xds_buffer_size = 0;
00452       
00453       /* read the expected size of the stream for this object */
00454       retval = GATXds_Decode(xds, GATXdsScope_Loan, buffer, 
00455         sizeof(buffer), "uint32", &xds_buffer_size);
00456       if (GAT_SUCCESS == retval)
00457       {
00458         /* reposition the input stream to start with the real object data */
00459         retval = GATStreamable_Seek(stream, GATOrigin_Current, 
00460           GATXds_GetBufferLen(xds) - xds_read_bytes, 0);
00461           
00462         if (GAT_SUCCESS == retval)
00463         {
00464           /* read the object data itself */
00465           char *xds_buffer = (char *)malloc(xds_buffer_size+1);
00466           if (NULL == xds_buffer)
00467           {
00468             retval = GAT_MEMORYFAILURE;
00469           }
00470           else 
00471           {
00472             memset(xds_buffer, 0, xds_buffer_size+1);
00473             if (GAT_SUCCESS == (retval = GATStreamable_Read(stream, 
00474                 xds_buffer, xds_buffer_size, 0)))
00475             {
00476               va_list args;
00477               GATuint32 *version = NULL;
00478               
00479               va_start(args, fmt);
00480 
00481               /* skip the leading uint32, it's the version item */
00482               if (0 != strncmp(fmt, "uint32", 6))
00483               {
00484                 /* the format string should start with uint32 for the version 
00485                   item */
00486                 retval = GAT_UNKNOWN_FORMAT;
00487               }
00488               else
00489               {
00490                 /* read the version */
00491                 version = va_arg(args, GATuint32 *);
00492                 retval = GATXds_Decode(xds, GATXdsScope_Gift, xds_buffer, 
00493                   xds_buffer_size, "uint32", version);
00494                 fmt += 7;    /* skip "uint32" and one additional character */
00495               }
00496               
00497               if (GAT_SUCCESS != retval || 
00498                   GATFalse == version_callback(*version))
00499               {
00500                 retval = GAT_UNKNOWN_FORMAT;
00501               }
00502               else 
00503               {
00504                 /* de-serialise the requested data items */
00505                 retval = GATXds_DecodeV(xds, (GATXdsScope)0, 0, 0, fmt, args);
00506                 if (GAT_SUCCESS == retval)
00507                 {
00508                   /* construct the new object */
00509                   retval = callback(context, stream, object, *version, args);
00510                 }
00511               }
00512             }
00513           }
00514         }
00515       }
00516     }
00517     GATXds_Destroy(&xds);
00518 
00519     /* FIXME: GATStatus(retval); */
00520   }
00521   return retval;
00522 }
00523 
00524 /** xml_encode_object
00525  *
00526  *  The function xml_encode_object
00527  */
00528 static int 
00529 xml_encode_object(xds_t *xds, void *engine_context, void *buffer, 
00530   size_t buffer_size, size_t *used_buffer_size, va_list *args)
00531 {
00532   int xds_error = XDS_ERR_NO_MEM;
00533   GATMemoryStream memory_stream = GATMemoryStream_Create(0, 0, GATFalse);
00534   
00535   /* Setup the engine. How long the actual content is going to be will be 
00536      seen soon. */
00537   xds_init_encoding_engine(1);  /* passed a '1' here to avoid warnings */
00538 
00539   if (NULL != memory_stream)
00540   {
00541     GATObject object = va_arg(*args, GATObject);
00542     GATBool clear_dirty = va_arg(*args, GATBool);
00543     GATResult retval = GAT_FAIL;
00544     GATObject stream_obj = GATMemoryStream_ToGATObject(memory_stream);
00545     
00546     retval = GATuint32_Serialise(NULL != object ? GATTrue : GATFalse, stream_obj);
00547     if (GAT_SUCCEEDED(retval) && NULL != object)
00548     {
00549       retval = GATSerialisable_Serialise(object, stream_obj, clear_dirty);
00550     }
00551     
00552     if (GAT_FAILED(retval))
00553     {
00554       xds_error = XDS_ERR_UNKNOWN;
00555     }  
00556     else
00557     {
00558       GATuint32 stream_buffer_size = 0;
00559       char *stream_buffer = (char *)GATMemoryStream_GetBuffer(memory_stream, 
00560         &stream_buffer_size, GATFalse);
00561       
00562       if (buffer_size > stream_buffer_size)
00563       {
00564         /* move data into the xds buffer */
00565         memmove(buffer, stream_buffer, stream_buffer_size);
00566         *used_buffer_size = stream_buffer_size;
00567         xds_error = XDS_OK;
00568       }
00569       else
00570       {
00571         /* return required buffer size */
00572         *used_buffer_size = stream_buffer_size;
00573         xds_error = XDS_ERR_OVERFLOW;
00574       }
00575     }
00576     GATMemoryStream_Destroy(&memory_stream);
00577   }
00578   return xds_error;
00579 }
00580 
00581 /** xml_decode_object
00582  *
00583  *  The function xml_decode_object
00584  */
00585 static int 
00586 xml_decode_object(xds_t *xds, void *engine_context, void *buffer, 
00587   size_t buffer_size, size_t *used_buffer_size, va_list *args)
00588 {
00589   int xds_error = XDS_ERR_TYPE_MISMATCH;
00590   
00591   if (NULL == engine_context)
00592   {
00593     xds_error = XDS_ERR_INVALID_MODE;
00594   }
00595   else
00596   {
00597     GATContext context = (GATContext) engine_context;
00598     GATMemoryStream memory_stream = GATMemoryStream_Create(buffer, buffer_size, 
00599       GATFalse);
00600     
00601     if (NULL == memory_stream)
00602     {
00603       xds_error = XDS_ERR_NO_MEM;
00604     }
00605     else
00606     {
00607       GATResult retval = GAT_SUCCESS;
00608       GATObject *object = va_arg(*args, GATObject *);
00609       GATObject stream_obj = GATMemoryStream_ToGATObject(memory_stream);
00610       GATuint32 hasobject = GATFalse;
00611       
00612       /* Setup the engine. How long the actual content is going to be will be 
00613         seen soon. */
00614       xds_init_encoding_engine(1);  /* passed a '1' here to avoid warnings */
00615       
00616       retval = GATuint32_DeSerialise(stream_obj, &hasobject);
00617       
00618       /* Decode the representation of the object. */
00619       if (GATTrue == hasobject)
00620       {
00621         *object = GATSerialisable_DeSerialise(context, stream_obj, &retval);
00622       }
00623       else
00624       {
00625         *object = NULL;  /* there was no object written */
00626       }
00627       
00628       if ((GATTrue == hasobject && NULL == *object) || GAT_FAILED(retval))
00629       {
00630         xds_error = XDS_ERR_TYPE_MISMATCH;
00631       }
00632       else
00633       { 
00634         GATuint32 offset = 0;
00635         
00636         retval = GATMemoryStream_Seek(memory_stream, GATOrigin_Current, 0, 
00637           &offset);
00638         if (GAT_SUCCESS == retval)
00639         {
00640           *used_buffer_size = offset;
00641           xds_error = XDS_OK;
00642         }
00643         else
00644         {
00645           xds_error = XDS_ERR_UNKNOWN;
00646         }
00647       }
00648     }
00649   
00650     GATMemoryStream_Destroy(&memory_stream);
00651   }
00652   return xds_error;
00653 }
00654 
00655 /*
00656  * Encode/decode double-precision floating point values.
00657  */
00658 
00659 int xml_encode_double_fmt(xds_t *xds, void *engine_context, void *buffer, 
00660   size_t buffer_size, size_t *used_buffer_size, va_list *args)
00661 {
00662   int xds_error = XDS_ERR_TYPE_MISMATCH;
00663   char format[sizeof("<double>%000.000lf</double>")+1];  /* should suffice */
00664   char *dbl_fmt = va_arg(*args, char *);
00665   
00666   assert(strlen(dbl_fmt) <= sizeof("%000.000lf"));
00667   
00668   xds_init_encoding_engine(8 + 9 + 1);
00669   snprintf(format, sizeof(format), "<double>%s</double>", dbl_fmt);
00670   *used_buffer_size = snprintf(buffer, buffer_size, format, 
00671     va_arg(*args, double));
00672   if (*used_buffer_size >= buffer_size)
00673   {
00674     xds_error = XDS_ERR_OVERFLOW;
00675   }
00676   else
00677   {
00678     xds_error = XDS_OK;
00679   }
00680   return xds_error;
00681 }
00682