GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



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

GATFileStream.c

Go to the documentation of this file.
00001 /** @file GATFileStream.c
00002  * Main .c for the GATFileStream class.
00003  * 
00004  * An GATFileStream represents a connection to another process.
00005  * 
00006  * @date $Date: 2004/04/09 12:29:18 $
00007  * 
00008  * @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATFileStream.c,v 1.11 2004/04/09 12:29:18 hartmutkaiser Exp $
00009  *
00010  *  Copyright (C) Kelly Davis
00011  *  This is part of the GAT Engine.
00012  *  Contributed by Kelly Davis <kdavis@aei.mpg.de>
00013  *
00014  *  Use, modification and distribution is subject to the Gridlab Software
00015  *  License. (See accompanying file GLlicense.txt or copy at
00016  *  http://www.gridlab.org/GLlicense.txt)
00017  */
00018  
00019 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATFileStream.c,v 1.11 2004/04/09 12:29:18 hartmutkaiser Exp $";
00020  
00021 /* System Header Files */
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <assert.h>
00027 
00028 /* GAT Header Files */
00029 #include "GAT.h"
00030 #include "GATRegistry.h"
00031 
00032 #include "GATInternal.h"
00033 #include "GATFileStreamCPI.h"
00034 #include "GATMetricEvent.h"
00035 
00036 /* define the vtable types */
00037 GATOBJECT_DEFINE_VTABLE(GATFileStream);
00038 GATSTREAMABLE_DEFINE_VTABLE(GATFileStream);
00039 GATMONITORABLE_DEFINE_VTABLE(GATFileStream);
00040 
00041 /* Declare the converters to/from GATObject */
00042 GATOBJECT_DEFINE_CONVERTERS(GATFileStream);
00043 
00044 /* Macros */
00045 
00046 /* Structures, unions and enums */
00047 struct GATFileStream_S
00048 {
00049   /* supported interfaces */
00050   GATFileStream_vtable *GATObject__vtable;
00051   GATFileStream_IStreamable_vtable *GATStreamable__vtable;
00052   GATFileStream_IMonitorable_vtable *GATMonitorable__vtable;
00053   
00054   /* instance data */
00055   GATFileStreamCPI_Instance data; /* instance data of the corresponding CPI object */
00056   GATFileStreamCPI cpi;           /* CPI object to use for all subsequent operations */
00057   GATFileStreamCPIList cpilist;   /* CPI list of appropriate CPI objects */
00058 };
00059 
00060 /* Static function prototypes */
00061 
00062 static GATResult
00063 GATFileStream_GetCPIInstanceData(GATFileStream filestream, void **data);
00064 
00065 /* FileStream scope variables */
00066 static GATFileStream_vtable GATFileStream__vtable = {
00067   GATFileStream_GetType,
00068   GATFileStream_Destroy,
00069   GATFileStream_Equals,
00070   GATFileStream_Clone,
00071   GATFileStream_GetInterface,
00072   GATFileStream_GetCPIInstanceData
00073 };
00074 
00075 static GATFileStream_IStreamable_vtable GATFileStream_IStreamable__vtable =
00076 {
00077   GATFileStream_Read,
00078   GATFileStream_Write,
00079   GATFileStream_Seek,
00080   GATFileStream_Close
00081 };
00082 
00083 static GATFileStream_IMonitorable_vtable  GATFileStream_IMonitorable__vtable = {
00084   GATFileStream_AddMetricListener,
00085   GATFileStream_RegisterPolling,
00086   GATFileStream_RemoveRegisteredMetric,
00087   GATFileStream_GetMetrics
00088 };
00089 
00090 /* External functions */
00091 
00092 /**
00093  *  Constructs an instance of this class.
00094  *
00095  * @param context Used to broker resources.
00096  * @param preferences User preferences for this instance.
00097  * @param location The location of the file to open
00098  * @param mode The mode in which to open the file (GATLogicalFileMode_Read, 
00099  * GATLogicalFileMode_Write, GATLogicalFileMode_Append, or GATLogicalFileMode_ReadWrite).
00100  */
00101 GATFileStream 
00102 GATFileStream_Create(GATContext context, GATPreferences_const preferences, 
00103   GATLocation location, GATFileStreamMode mode)
00104 {
00105   GAT_STATUS_APIENTRY(context, "GATFileStream_Create");
00106   
00107   GATFileStream new_fileStream = (GATFileStream) malloc(sizeof(struct GATFileStream_S));
00108   if(NULL != new_fileStream)
00109   {
00110     memset(new_fileStream, 0, sizeof(struct GATFileStream_S));
00111     new_fileStream->GATObject__vtable = &GATFileStream__vtable;
00112     new_fileStream->GATStreamable__vtable = &GATFileStream_IStreamable__vtable;
00113     new_fileStream->GATMonitorable__vtable = &GATFileStream_IMonitorable__vtable;
00114 
00115     new_fileStream->data.mode = mode;
00116     new_fileStream->data.context = context;
00117     new_fileStream->data.source = GATFileStream_ToGATObject_const(new_fileStream);
00118 
00119     /* find a CPI object, which can handle the fileStream */
00120     {
00121       GATRegistry_const registry = GATContext_internal_GetRegistry(context);
00122       
00123       GAT_CREATE_STATUS(GATLocation_Clone(location, &new_fileStream->data.location));
00124 
00125       /* use default preferences, if appropriate */
00126       if (NULL == preferences)
00127       {
00128         preferences = GATContext_GetPreferences(context);
00129       }
00130       new_fileStream->cpilist = GATRegistry_FindGATFileStreamCPI(registry, preferences);
00131 
00132       if (NULL == new_fileStream->cpilist)
00133       {
00134         GAT_CREATE_STATUS(GAT_NO_REGISTERED_CPI);
00135       } 
00136       else if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00137       {
00138         /* create a new instance of the CPI provider */
00139         GATBool found_cpi = GATFalse;
00140         GATFileStreamCPIList current = NULL;
00141         for(current = new_fileStream->cpilist; NULL != current; current = current->next)
00142         {
00143           GAT_CREATE_STATUS(GATFileStreamCPI_CreateInstance(current->cpi, 
00144             &new_fileStream->data));
00145           if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00146           {
00147             new_fileStream->cpi = current->cpi;
00148             found_cpi = GATTrue;
00149             break;
00150           }
00151         }
00152 
00153         /* no available CPI object can handle this */
00154         if (GATFalse == found_cpi)
00155         {
00156           GAT_CREATE_STATUS(GAT_NO_REGISTERED_CPI);
00157         }
00158         else
00159         {
00160           /* now, initialise the monitoring framework with the help of the CPI 
00161              provider found */
00162           GATList_GATMetric metrics = NULL;
00163           GATResult retval = GATFileStreamCPI_GetMetrics(new_fileStream->cpi, 
00164             &new_fileStream->data, &metrics);            
00165 
00166           if (GAT_SUCCEEDED(retval))
00167           {
00168             new_fileStream->data.monitorable = GATMonitorable_Impl_Create(metrics);
00169             if (NULL == new_fileStream->data.monitorable)
00170             {
00171               GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00172             }
00173             GATList_GATMetric_Destroy(&metrics);
00174           }
00175           else if (GAT_NOTIMPL == retval)
00176           {
00177             retval = GAT_SUCCESS;   /* no monitoring supported here */
00178           }
00179           else
00180           {
00181             GAT_CREATE_STATUS(retval);
00182           }
00183           
00184           /* register this object with the engine */
00185           GAT_CREATE_STATUS(GATRegistry_AddGATFileStreamToCPIList(context, 
00186               new_fileStream->cpi, new_fileStream));
00187         }
00188       }
00189     }
00190   }
00191   else
00192   {
00193     GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00194   }
00195   
00196   /* error handling */
00197   if (GAT_FAILED(GAT_CURRENT_STATUS()))
00198   {
00199     GATFileStream_Destroy(&new_fileStream);
00200   }
00201   
00202   GAT_STORE_STATUS();
00203   return new_fileStream;
00204 }
00205 
00206 /** GATFileStream_Destroy
00207  *  The GATFileStream destructor.
00208  *  This is the destructor for GATFileStream objects.
00209  *
00210  * @param fileStream An old GATFileStream
00211  */
00212 void GATFileStream_Destroy(GATFileStream *fileStream)
00213 {
00214   if(NULL != fileStream && NULL != *fileStream)
00215   {
00216     GATMonitorable_Impl_Destroy(&(*fileStream)->data.monitorable);
00217     if (NULL != (*fileStream)->cpi)
00218     {
00219       GATRegistry_RemoveGATFileStreamFromCPIList((*fileStream)->data.context, 
00220         (*fileStream)->cpi, *fileStream);
00221       GATFileStreamCPI_DestroyInstance((*fileStream)->cpi, &(*fileStream)->data);
00222     }
00223     GATLocation_Destroy(&(*fileStream)->data.location);
00224     GATFileStreamCPIList_Destroy((*fileStream)->cpilist);
00225     free(*fileStream);
00226     *fileStream = NULL;
00227   }
00228 }
00229 
00230 /** int GATFileStream_GetType(GATFileStream_const fileStream)
00231  *  @brief Return the type of the GATFileStream
00232  *
00233  *  The function @c GATFileStream_GetType always returns GATType_GATFileStream. 
00234  *
00235  *  @param fileStream The object to inspect
00236  *
00237  *  @return returns always @c #GATType_GATFileStream.
00238  */
00239 GATType GATFileStream_GetType(GATFileStream_const fileStream)
00240 {
00241   GAT_UNUSED_PARAMETER(fileStream);
00242   return GATType_GATFileStream;
00243 }
00244 
00245 /** int GATFileStream_Clone(GATFileStream_const fileStream, GATFileStream *new_fileStream)
00246  *  @brief Clone the given GATFileStream
00247  *
00248  *  The function @c GATFileStream_Clone generates a (deep) copy of the given
00249  *  GATFileStream. 
00250  *
00251  *  @param new_object The object to clone
00252  *  @param new_fileStream The pointer, through which the result is to be 
00253  *        returned.
00254  *
00255  *  @return An error type.
00256  */
00257 GATResult 
00258 GATFileStream_Clone(GATFileStream_const fileStream, GATFileStream *new_object)
00259 {
00260   if (NULL != fileStream)
00261   {
00262     GAT_STATUS_APIENTRY(fileStream->data.context, "GATFileStream_Clone");
00263     
00264     if (NULL != new_object)
00265     {
00266       struct GATFileStream_S const *passedFileStream = fileStream;
00267       GATFileStream new_fileStream = (GATFileStream) malloc(sizeof(struct GATFileStream_S));
00268       
00269       *new_object = NULL;
00270       if (NULL == new_fileStream)
00271       {
00272         GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00273       }
00274       else
00275       {
00276         memset(new_fileStream, 0, sizeof(struct GATFileStream_S));
00277         new_fileStream->GATObject__vtable = &GATFileStream__vtable;
00278         new_fileStream->GATStreamable__vtable = &GATFileStream_IStreamable__vtable;
00279         new_fileStream->GATMonitorable__vtable = &GATFileStream_IMonitorable__vtable;
00280         
00281         new_fileStream->data.mode = passedFileStream->data.mode;
00282         new_fileStream->data.context = passedFileStream->data.context;
00283         new_fileStream->data.source = GATFileStream_ToGATObject_const(new_fileStream);
00284         new_fileStream->cpilist = GATRegistry_CloneGATFileStreamCPIList(passedFileStream->cpilist);
00285         
00286         if (NULL == new_fileStream->cpilist)
00287         {
00288           GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00289         }
00290         GAT_CREATE_STATUS(GATLocation_Clone(passedFileStream->data.location, 
00291           &new_fileStream->data.location));
00292                 
00293         if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()))
00294         {
00295           /* re-find the cpi to use */
00296           GATFileStreamCPIList current = passedFileStream->cpilist;
00297           GATFileStreamCPIList new_current = new_fileStream->cpilist;
00298           
00299           for (/**/; NULL != current; 
00300                current = current->next, new_current = new_current->next)
00301           {
00302             if (current->cpi == passedFileStream->cpi)
00303             {
00304               new_fileStream->cpi = new_current->cpi;
00305               break;
00306             }
00307           }
00308           assert(NULL != new_fileStream->cpi);
00309           
00310           /* clone the instance data */
00311           GAT_CREATE_STATUS(GATFileStreamCPI_CloneInstance(passedFileStream->cpi, &passedFileStream->data, 
00312             &new_fileStream->data));
00313 
00314           /* clone the monitoring data */
00315           if (NULL != passedFileStream->data.monitorable)
00316           {
00317             GAT_CREATE_STATUS(GATMonitorable_Impl_Clone(passedFileStream->data.monitorable, 
00318               &new_fileStream->data.monitorable));
00319           }
00320             
00321           /* register this object with the engine */
00322           GAT_CREATE_STATUS(GATRegistry_AddGATFileStreamToCPIList(
00323             new_fileStream->data.context, new_fileStream->cpi, new_fileStream));
00324         }
00325       }
00326 
00327       /* destroy the newly allocated object, if some error occured */
00328       if (GAT_FAILED(GAT_CURRENT_STATUS()))
00329       {
00330         GATFileStream_Destroy(&new_fileStream);
00331       }
00332       else
00333       {
00334         /* return the new object */
00335         *new_object = new_fileStream;
00336       }
00337     }
00338     else
00339     {
00340       GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00341     }
00342     
00343     return GAT_RETURN_STATUS();
00344   }
00345   return GAT_INVALID_HANDLE;
00346 }
00347 
00348 /** int GATFileStream_Equals(GATFileStream_const lhs, GATFileStream_const rhs, GATBool *isequal)
00349  *  @brief Compares two GATFileStream objects
00350  *
00351  *  The function @c GATFileStream_Equals compares two fileStream objects of type 
00352  *  @c #GATFileStream.
00353  *
00354  *  @param lhs The first fileStream object to compare
00355  *  @param rhs The second fileStream object to compare
00356  *  @param isequal The pointer to the GATBool variable, which should receive 
00357  *        the result if the comparision
00358  *
00359  *  @return An error code.
00360  */
00361 GATResult 
00362 GATFileStream_Equals(GATFileStream_const lhs, GATFileStream_const rhs, GATBool *isequal)
00363 {
00364   if (NULL != lhs && NULL != rhs)
00365   {
00366     GAT_STATUS_APIENTRY(lhs->data.context, "GATFileStream_Equals");
00367     if (NULL != isequal)
00368     {
00369       GAT_CREATE_STATUS(GATLocation_Equals(lhs->data.location, 
00370         rhs->data.location, isequal));
00371 
00372       if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()) && GATTrue == *isequal)
00373       {
00374         if (lhs->data.mode != rhs->data.mode) 
00375         {
00376           *isequal = GATFalse;
00377         }
00378         if (GATTrue == *isequal)
00379         {
00380           GAT_CREATE_STATUS(GATFileStreamCPI_EqualsInstance(lhs->cpi, 
00381             &lhs->data, &rhs->data, isequal));
00382         }
00383       }
00384     }
00385     return GAT_RETURN_STATUS();
00386   }
00387   return GAT_INVALID_HANDLE;
00388 }
00389 
00390 /** int GATFileStream_GetInterface(GATFileStream_const fileStream, GATInterface iftype, void const **ifp)
00391  *  @brief Get an interface supported by a GATObject
00392  *
00393  *  The function GATFileStream_GetInterface allows to get a pointer to an 
00394  *  additional interface supported by this GATFileStream.
00395  *
00396  *  @param object The object to be asked for the new interface.
00397  *  @param iftype The interface the object is to be asked for.
00398  *  @param ifp The pointer, through which the result is to be returned.
00399  *
00400  *  @return An error type.
00401  */
00402 GATResult 
00403 GATFileStream_GetInterface(GATFileStream_const fileStream, GATInterface iftype, 
00404   void const **ifp)
00405 {
00406   if (NULL != fileStream)
00407   {
00408     GAT_STATUS_APIENTRY(fileStream->data.context, "GATFileStream_GetInterface");
00409     
00410     if (NULL != ifp)
00411     {
00412       if (GATInterface_IStreamable == iftype)
00413       {
00414         *ifp = (void const *) &fileStream->GATStreamable__vtable;
00415       }
00416       else if (GATInterface_IMonitorable == iftype && NULL != fileStream->data.monitorable)
00417       {
00418         *ifp = (void const *) &fileStream->GATMonitorable__vtable;
00419       }
00420       else
00421       {
00422         *ifp = NULL;
00423         GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00424       }
00425     }
00426     else
00427     {
00428         GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00429     }
00430     
00431     return GAT_RETURN_STATUS();
00432   }
00433   return GAT_INVALID_HANDLE;
00434 }
00435 
00436 /* GATMonitorable */
00437 
00438 /** GATFileStream_AddMetricListener
00439  *
00440  *  The function GATFileStream_AddMetricListener adds the passed instance of a 
00441  *  GATMetricListener to the list of GATMetricListeners which are notified of 
00442  *  fired GATMetricEvents of the type described by the provided GATMetric 
00443  *  instance.
00444  *
00445  *  @param fileStream The GATFileStream instance to add the GATMetricListener to.
00446  *  @param listener The GTAMetricListener to call, when the corresponding 
00447  *        GATMetricEvent is fired.
00448  *  @param listener_data The client supplied data, which will be passed through
00449  *        to the GATMetricListener.
00450  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00451  *        to the GATMetricListener.
00452  *  @param cookie The returned value should be used to remove the 
00453  *        GATMetricListener from this GATMonitorable.
00454  *
00455  *  @return An error code.
00456  */ 
00457 GATResult 
00458 GATFileStream_AddMetricListener(GATFileStream fileStream, GATMetricListener listener,
00459   void *listener_data, GATMetric metric, GATuint32 *cookie)
00460 {
00461   if (NULL != fileStream)
00462   {
00463     GAT_STATUS_APIENTRY(fileStream->data.context, "GATFileStream_AddMetricListener");
00464     
00465     if (NULL != fileStream->data.monitorable)
00466     {
00467       GAT_CREATE_STATUS(GATMonitorable_Impl_AddMetricListener(fileStream->data.monitorable, 
00468         listener, listener_data, metric, cookie));
00469     } 
00470     else
00471     { 
00472       /* this may happen, if the adaptor has not registered any GATMetrics */
00473       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00474     }
00475     
00476     return GAT_RETURN_STATUS();
00477   }
00478   return GAT_INVALID_HANDLE;
00479 }
00480 
00481 /** GATFileStream_RegisterPolling
00482  *
00483  *  The function GATFileStream_RegisterPolling registers a continuous 
00484  *  metric with the given GATFileStream instance.
00485  *
00486  *  @param fileStream The GATFileStream instance to register the metric with.
00487  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00488  *        to the GATMetricListener. This metric instance must be of type
00489  *        GATMeasurementType_Continuous, otherwise an error is returned.
00490  *  @param event The pointer to a variable, which should receive the resulting
00491  *        GATMetricEvent. The GATMetricEvent instance should be freed by the 
00492  *        caller when it isn't used anymore.
00493  *  @param cookie The returned value should be used to remove the 
00494  *        GATMetricListener from this GATFileStream.
00495  *
00496  *  @return An error code.
00497  */ 
00498 GATResult 
00499 GATFileStream_RegisterPolling(GATFileStream fileStream, GATMetric metric, GATMetricEvent *event, 
00500   GATuint32 *cookie)
00501 {
00502   if (NULL != fileStream)
00503   {
00504     GAT_STATUS_APIENTRY(fileStream->data.context, "GATFileStream_RegisterPolling");
00505     
00506     if (NULL != fileStream->data.monitorable)
00507     {
00508       GAT_CREATE_STATUS(GATMonitorable_Impl_RegisterPolling(fileStream->data.monitorable, 
00509         metric, 0, cookie));
00510 
00511       /* ask the CPI provider to return the corresponding metric event */
00512       GAT_CREATE_STATUS(GATFileStreamCPI_GetMetricEvent(fileStream->cpi, &fileStream->data, metric, 
00513         event));
00514 
00515       if (GAT_SUCCEEDED(GAT_CURRENT_STATUS()) && NULL != cookie && 0 != *cookie)
00516       {
00517         GATMonitorable_Impl_RemoveRegisteredMetric(fileStream->data.monitorable,
00518           metric, *cookie);
00519         *cookie = 0;
00520       }
00521     } 
00522     else
00523     { 
00524       /* this may happen, if the adaptor has not registered any GATMetrics */
00525       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00526     }
00527     
00528     return GAT_RETURN_STATUS();
00529   }
00530   return GAT_INVALID_HANDLE;
00531 }
00532 
00533 /** GATFileStream_RemoveRegisteredMetric
00534  *
00535  *  The function GATFileStream_RemoveRegisteredMetric removes a GATMetricListener, 
00536  *  which was previously registered with GATFileStream_AddMetricListener.
00537  *
00538  *  @param fileStream The GATFileStream instance to remove the GATMetricListener from.
00539  *  @param metric The GATMetric instance describing the GATMetricEvent to pass
00540  *        to the GATMetricListener.
00541  *  @param cookie This value identifies the GATMetricListener to remove, it 
00542  *        was returned from the corresponding GATMonitorable_AddMetricListener 
00543  *        or GATMonitorable_MetricRegisterPolling functions.
00544  *  
00545  *  @return An error code.
00546  */
00547 GATResult 
00548 GATFileStream_RemoveRegisteredMetric(GATFileStream fileStream, GATMetric metric, 
00549   GATuint32 cookie)
00550 {
00551   if (NULL != fileStream)
00552   {
00553     GAT_STATUS_APIENTRY(fileStream->data.context, "GATFileStream_RemoveRegisteredMetric");
00554     
00555     if (NULL != fileStream->data.monitorable)
00556     {
00557       GAT_CREATE_STATUS(GATMonitorable_Impl_RemoveRegisteredMetric(
00558         fileStream->data.monitorable, metric, cookie));
00559     } 
00560     else
00561     { 
00562       /* this may happen, if the adaptor has not registered any GATMetrics */
00563       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00564     }
00565     
00566     return GAT_RETURN_STATUS();
00567   }
00568   return GAT_INVALID_HANDLE;
00569 }
00570 
00571 /** GATFileStream_GetMetrics
00572  *
00573  *  The function GATFileStream_GetMetrics returns a list of metrics supported by this
00574  *  GATFileStream.
00575  *
00576  *  @param fileStream The GATFileStream instance, for which the supported metrics should be 
00577  *        returned.
00578  *  @param metrics The pointer to the variable, which receives the resulting 
00579  *        list of metrics.
00580  *
00581  *  @return An error code.
00582  */
00583 GATResult 
00584 GATFileStream_GetMetrics(GATFileStream_const fileStream, 
00585   GATList_GATMetric *metrics)
00586 {
00587   if (NULL != fileStream)
00588   {
00589     GAT_STATUS_APIENTRY(fileStream->data.context, "GATFileStream_GetMetrics");
00590     
00591     if (NULL != fileStream->data.monitorable)
00592     {
00593       GAT_CREATE_STATUS(GATMonitorable_Impl_GetMetrics(
00594         fileStream->data.monitorable, metrics));
00595     } 
00596     else
00597     { 
00598       /* this may happen, if the adaptor has not registered any GATMetrics */
00599       GAT_CREATE_STATUS(GAT_NO_INTERFACE);
00600     }
00601     
00602     return GAT_RETURN_STATUS();
00603   }
00604   return GAT_INVALID_HANDLE;
00605 }
00606 
00607 
00608 /* IStreamable implementation */
00609 
00610 /* Reads from this GATStreamable into the given buffer */
00611 GATResult 
00612 GATFileStream_Read(GATFileStream object, void *buffer, GATuint32 size, 
00613   GATuint32 *read_bytes)
00614 {
00615   if (NULL != object)
00616   {
00617     GAT_STATUS_APIENTRY(object->data.context, "GATFileStream_Read");
00618     GAT_CREATE_STATUS(GATFileStreamCPI_Read(object->cpi, &object->data, buffer, 
00619       size, read_bytes));
00620     return GAT_RETURN_STATUS();
00621   }
00622   return GAT_INVALID_HANDLE;
00623 }
00624 
00625 /* Writes data from the given Buffer through the GATStreamable */
00626 GATResult 
00627 GATFileStream_Write(GATFileStream object, void const *buffer, GATuint32 size, 
00628   GATuint32 *written_bytes)
00629 {
00630   if (NULL != object)
00631   {
00632     GAT_STATUS_APIENTRY(object->data.context, "GATFileStream_Write");
00633     GAT_CREATE_STATUS(GATFileStreamCPI_Write(object->cpi, &object->data, 
00634       buffer, size, written_bytes));
00635     return GAT_RETURN_STATUS();
00636   }
00637   return GAT_INVALID_HANDLE;
00638 }
00639 
00640 /* reposition the internal stream position */
00641 GATResult 
00642 GATFileStream_Seek(GATFileStream object, GATOrigin origin, GATint32 offset, 
00643   GATuint32 *new_position)
00644 {
00645   if (NULL != object)
00646   {
00647     GAT_STATUS_APIENTRY(object->data.context, "GATFileStream_Seek");
00648     GAT_CREATE_STATUS(GATFileStreamCPI_Seek(object->cpi, &object->data, origin, 
00649       offset, new_position));
00650     return GAT_RETURN_STATUS();
00651   }
00652   return GAT_INVALID_HANDLE;
00653 }
00654     
00655 /* Closes this GATStreamable instance. */
00656 GATResult GATFileStream_Close(GATFileStream object)
00657 {
00658   if (NULL != object)
00659   {
00660     GAT_STATUS_APIENTRY(object->data.context, "GATFileStream_Close");
00661     GAT_CREATE_STATUS(GATFileStreamCPI_Close(object->cpi, &object->data));
00662     return GAT_RETURN_STATUS();
00663   }
00664   return GAT_INVALID_HANDLE;
00665 }
00666 
00667 
00668 /* Local functions */
00669 
00670 /*  GATFileStream_GetCPIInstanceData
00671  *  
00672  *  The function GATFileStream_GetCPIInstanceData returns the CPI instance data, 
00673  *  associated with the given GATFile object.
00674  *
00675  *  @param filestream The object, for which to return the CPI instance data.
00676  *  @param data The pointer to the variable, which should receive the
00677  *        resulting CPI instance data.
00678  *
00679  *  @return An error code.
00680  */
00681 static GATResult
00682 GATFileStream_GetCPIInstanceData(GATFileStream filestream, void **data)
00683 {
00684   if (NULL != filestream)
00685   {
00686     GAT_USES_STATUS(filestream->data.context, "GATFileStream_GetCPIInstanceData");
00687     
00688     if (NULL != data)
00689     {
00690       *data = (void *)&filestream->data;
00691     }
00692     else
00693     {
00694       GAT_CREATE_STATUS(GAT_INVALID_PARAMETER);
00695     }
00696     
00697     return GAT_RETURN_STATUS();
00698   }
00699   return GAT_INVALID_HANDLE;
00700 }
00701