GridLab
Grid Application Toolkit

A simple API for Grid Applications
GAT

Menu



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

logical_filestore.c

Go to the documentation of this file.
00001 /** @file logical_filestore.c
00002  * Source file for the logical_filestore class.
00003  *
00004  * @date Thu Oct 16 2003
00005  *
00006  * @version $Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/adaptors/logicalfile/logical_filestore.c,v 1.13 2004/04/02 12:31:57 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/adaptors/logicalfile/logical_filestore.c,v 1.13 2004/04/02 12:31:57 hartmutkaiser Exp $";
00018 
00019 /* system headers */
00020 #include <stdio.h>
00021 #include <stdlib.h>
00022 #include <string.h>
00023 
00024 /* GAT headers */
00025 #include "GATUtil.h"
00026 #include "GATErrors.h"
00027 #include "GATStatus.h"
00028 #include "GATContext.h"
00029 #include "GATFile.h"
00030 #include "GATLocation.h"
00031 #include "GATList.h"
00032 
00033 #include "logical_filestore.h"
00034 
00035 /* static prototypes */
00036 static GATResult 
00037   logical_filestore_init(GATContext ctx, logical_filestore store, GATLogicalFileMode mode);
00038 static GATResult 
00039   logical_filestore_flush(GATContext ctx, logical_filestore store);
00040 
00041 /* external functions */
00042 
00043 /*
00044  *  Create a new logical filestore from the contents of the given file, which
00045  *  should contain a list of file names to use.
00046  */
00047 logical_filestore 
00048 logical_filestore_create(GATContext ctx, char const *name, 
00049   GATLogicalFileMode mode)
00050 {
00051   logical_filestore new_store = 
00052     (logical_filestore)malloc(sizeof(struct logical_filestore_s));
00053   
00054   if (NULL != new_store)
00055   {
00056     /* init internal data members */
00057     memset(new_store, 0, sizeof(struct logical_filestore_s));
00058     new_store->context = ctx;
00059     new_store->isdirty = GATFalse;
00060     new_store->shouldberemoved = GATFalse;
00061     new_store->name = GATUtil_strdup(name);
00062     if (NULL == new_store->name)
00063     {
00064       free(new_store);
00065       new_store = NULL;
00066     }
00067     
00068     new_store->files = GATList_String_Create();
00069     if (NULL == new_store->files)
00070     {
00071       logical_filestore_destroy(ctx, &new_store);
00072     }
00073     
00074     /* try to read existing logical filestore */
00075     if (NULL != new_store)
00076     {
00077       int retval = logical_filestore_init(ctx, new_store, mode);
00078       if (GAT_SUCCESS != retval)
00079       {
00080         logical_filestore_destroy(ctx, &new_store);
00081       }
00082     }
00083   }
00084   return new_store;
00085 }
00086 
00087 /*
00088  *  Destroy the given logical filestore
00089  */
00090 void 
00091 logical_filestore_destroy(GATContext ctx, logical_filestore *store)
00092 {
00093   if (NULL != store && NULL != *store)
00094   {
00095     if (GATTrue == (*store)->shouldberemoved)
00096     {
00097       unlink((*store)->name);   /* simply remove the file */
00098     }
00099     else
00100     {
00101       /* write the filestore to disk (if needed) */
00102       if (GATTrue == (*store)->isdirty)
00103       {
00104         logical_filestore_flush(ctx, *store);
00105       }
00106     }
00107         
00108     /* free the allocated memory */
00109     GATList_String_Destroy(&(*store)->files);
00110     free((char *)(*store)->name);
00111     free(*store);
00112     *store = NULL;
00113   }
00114 }
00115 
00116 /*
00117  *  Add a given file to the logical file store
00118  */
00119 GATResult 
00120 logical_filestore_addfile(GATContext ctx, logical_filestore store, 
00121   GATFile_const file)
00122 {
00123   GAT_USES_STATUS(ctx, "logical_filestore_addfile");
00124 
00125   GATLocation_const location = GATFile_GetLocation(file);
00126   char *filename = GATLocation_ToString(location);
00127   GATList_String_Iterator it = GATList_String_Insert(store->files, 
00128     GATList_String_End(store->files), filename);
00129   
00130   if (NULL != it) 
00131   {
00132     store->isdirty = GATTrue;
00133   }
00134   else
00135   {
00136     GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00137   }
00138   
00139   free(filename);
00140   return GAT_RETURN_STATUS();
00141 }
00142 
00143 /*
00144  *  Remove a given file from the logical file store
00145  */
00146 GATResult 
00147 logical_filestore_removefile(GATContext ctx, logical_filestore store, 
00148   GATFile_const file)
00149 {
00150   GAT_USES_STATUS(ctx, "logical_filestore_removefile");
00151 
00152   GATList_String_Iterator end = GATList_String_End(store->files);
00153   GATList_String_Iterator it = GATList_String_Begin(store->files);
00154   GATLocation_const location = GATFile_GetLocation(file);
00155   char *filename = GATLocation_ToString(location);
00156   
00157   for (/**/; it != end; it = GATList_String_Next(it))
00158   {
00159     char const *name = GATList_String_Get(it);
00160     if (NULL == name)
00161     {
00162       GAT_CREATE_STATUS(GAT_FAIL);
00163       break;
00164     }
00165     
00166     if (!strcmp(name, filename))
00167     {
00168       GATList_String_Erase(store->files, it);
00169       store->isdirty = GATTrue;
00170       break;
00171     }
00172   }
00173   
00174   free(filename);
00175   return GAT_RETURN_STATUS();
00176 }
00177 
00178 /*
00179  *  Replicate the logical file store to the given location
00180  */
00181 GATResult 
00182 logical_filestore_replicate(GATContext ctx, logical_filestore store, 
00183   GATLocation_const target)
00184 {
00185   GAT_USES_STATUS(ctx, "logical_filestore_replicate");
00186 
00187   GATList_String_Iterator end = GATList_String_End(store->files);
00188   GATList_String_Iterator it = GATList_String_Begin(store->files);
00189   
00190   if (it != end)
00191   {
00192     char const *name = GATList_String_Get(it);
00193     if (NULL != name)
00194     {
00195       /* use the GAT to copy this file over to the new location */
00196       GATLocation source = GATLocation_Create(name);
00197       if (NULL != source)
00198       {
00199         GATFile file = GATFile_Create(ctx, source, 0);
00200         if (NULL != file)
00201         {
00202           GAT_CREATE_STATUS(GATFile_Copy(file, target, GATFileMode_Overwrite));
00203           GATFile_Destroy(&file);
00204         }
00205         else
00206         {
00207           GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00208         }
00209         GATLocation_Destroy(&source);
00210       }
00211       else
00212       {
00213         GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00214       }
00215     }
00216   }
00217   return GAT_RETURN_STATUS();
00218 }
00219 
00220 /*
00221  *  Return a list containing all files of a given logical file store
00222  */
00223 GATResult 
00224 logical_filestore_getfiles(GATContext ctx, logical_filestore store, GATList_GATFile *files_)
00225 {
00226   GAT_USES_STATUS(ctx, "logical_filestore_getfiles");
00227 
00228   GATList_GATFile files = GATList_GATFile_Create();
00229   
00230   if (NULL != files)
00231   {
00232     GATList_String_Iterator end = GATList_String_End(store->files);
00233     GATList_String_Iterator it = GATList_String_Begin(store->files);
00234 
00235     for (/**/; it != end; it = GATList_String_Next(it))
00236     {
00237       char const *name = GATList_String_Get(it);
00238 
00239       if (NULL != name)
00240       {
00241         GATLocation location = GATLocation_Create(name);
00242         if (NULL != location)
00243         {
00244           GATFile file = GATFile_Create(store->context, location, 0);
00245           if (NULL != file)
00246           {
00247             GATList_GATFile_Iterator element = GATList_GATFile_Insert(files, 
00248               GATList_GATFile_End(files), file);
00249             GAT_CREATE_STATUS_IF(NULL == element, GAT_MEMORYFAILURE);
00250             GATFile_Destroy(&file);
00251           }
00252           GATLocation_Destroy(&location);
00253         }
00254       }
00255       else
00256       {
00257         GAT_CREATE_STATUS(GAT_FAIL);
00258       }
00259       
00260       if (GAT_SUCCESS != GAT_CURRENT_STATUS())
00261       {
00262         GATList_GATFile_Destroy(&files);
00263         break;
00264       }
00265     }
00266   }
00267 
00268   *files_ = files;
00269 
00270   return GAT_RETURN_STATUS();
00271 }
00272 
00273 /*
00274  *  Remove the logical file store
00275  */
00276 GATResult 
00277 logical_filestore_remove(logical_filestore store)
00278 {
00279   store->shouldberemoved = GATTrue;
00280   return GAT_SUCCESS;
00281 }
00282 
00283 /* static functions */
00284 
00285 /*
00286  *  Read in the contents of a given file store
00287  */
00288 static GATResult 
00289 logical_filestore_init(GATContext ctx, logical_filestore store, 
00290   GATLogicalFileMode mode)
00291 {
00292   GAT_USES_STATUS(ctx, "logical_filestore_init");
00293 
00294   FILE *f = fopen(store->name, "r");
00295   if (NULL != f)
00296   {
00297     if (GATLogicalFileMode_Truncate != mode)
00298     {
00299       char buffer[4096];
00300       
00301       /* read back current contents */
00302       while (NULL != fgets(buffer, sizeof(buffer), f))
00303       {
00304         GATList_String_Iterator it = NULL;
00305         char *eol = strchr(buffer, '\n');
00306         if (NULL != eol)
00307         {
00308           *eol = '\0';   /* remove trailing '\n' */
00309         }
00310         
00311         it = GATList_String_Insert(store->files, 
00312           GATList_String_End(store->files), buffer);
00313         if (NULL == it)
00314         {
00315           GAT_CREATE_STATUS(GAT_MEMORYFAILURE);
00316           break;
00317         }
00318       }
00319     }
00320     fclose(f);
00321   }
00322   else if (GATLogicalFileMode_Create != mode)
00323   {
00324     /* file should exist */
00325     GAT_CREATE_STATUS(GAT_FILEOPEN_ERROR);
00326   }
00327   return GAT_RETURN_STATUS();
00328 }
00329 
00330 /*
00331  *  Write the contents of a file store to disk
00332  */
00333 static GATResult 
00334 logical_filestore_flush(GATContext ctx, logical_filestore store)
00335 {
00336   GAT_USES_STATUS(ctx, "logical_filestore_flush");
00337 
00338   FILE *f = fopen(store->name, "w+");
00339   if (NULL != f)
00340   {
00341     GATList_String_Iterator end = GATList_String_End(store->files);
00342     GATList_String_Iterator it = GATList_String_Begin(store->files);
00343     
00344     for (/**/; it != end; it = GATList_String_Next(it))
00345     {
00346       char const *name = GATList_String_Get(it);
00347       if (NULL != name)
00348       {
00349         if (EOF == fputs(name, f) || EOF == fputs("\n", f))
00350         {
00351           GAT_CREATE_STATUS(GAT_FAIL);
00352           break;
00353         }
00354       }
00355       else
00356       {
00357         GAT_CREATE_STATUS(GAT_FAIL);
00358         break;
00359       }
00360     }
00361     fclose(f);
00362   }
00363   return GAT_RETURN_STATUS();
00364 }
00365